unofficial mirror of emacs-devel@gnu.org 
 help / color / mirror / code / Atom feed
* New major mode using cc-mode => cc-mode intrudes unrelated modes
@ 2007-06-27 19:28 Jens Peter Secher
  2007-06-29 16:22 ` Vagn Johansen
  2007-07-16 22:42 ` Alan Mackenzie
  0 siblings, 2 replies; 5+ messages in thread
From: Jens Peter Secher @ 2007-06-27 19:28 UTC (permalink / raw)
  To: emacs-devel

[-- Attachment #1: Type: text/plain, Size: 1047 bytes --]

I have been trying to create a major mode for a programming language
called haXe, but I have run into problems.  haxe-mode is basically just
a cut-down version of java-mode, as you can see from the first attached
file.

The problems is that, efter putting a buffer in haxe-mode, cc-mode
functions intrude into others modes, eg. lisp-mode.  More specifically,
after visiting the haxe-mode test file in the second attachment, a newly
created lisp-mode buffer will have eg. beginning-of-defun-function set
to c-beginning-of-defun.

Another strange thing is that I have to set comment-start-skip
explicitly in haxe-mode, otherwise it gets a nil value when visiting
haxe-mode files.

So obviously I am doing something wrong, but I cannot figure out what.

I am using Emacs 22.0.99.1 (including cc-mode 5.31.4).

Cheers,
-- 
                                                    Jens Peter Secher.
_DD6A 05B0 174E BFB2 D4D9 B52E 0EE5 978A FE63 E8A1 jpsecher gmail com_.
A. Because it breaks the logical sequence of discussion.
Q. Why is top posting bad?


[-- Attachment #2: haxe-mode --]
[-- Type: text/plain, Size: 10846 bytes --]

;;; Commentary:

;; ------------------------------------------------------------------------
;; Copyright (C) 2006-2007 Jens Peter Secher
;;
;; This software is provided 'as-is', without any express or implied
;; warranty.  In no event will the author be held liable for any
;; damages arising from the use of this software.
;;
;; Permission is granted to anyone to use this software for any
;; purpose, including commercial applications, and to alter it and
;; redistribute it freely, subject to the following restrictions:
;;
;; 1. The origin of this software must not be misrepresented; you must
;;    not claim that you wrote the original software.  If you use this
;;    software in a product, an acknowledgment in the product
;;    documentation would be appreciated but is not required.
;; 2. Altered source versions must be plainly marked as such, and must
;;    not be misrepresented as being the original software.
;; 3. This notice may not be removed or altered from any source
;;    distribution.
;; ------------------------------------------------------------------------

;; This is haxe-mode, an Emacs major mode for the haXe programming
;; language (http://haxe.org).

;; haxe-mode is built on top of the excellent cc-mode, inspired by the
;; guide http://cc-mode.sourceforge.net/derived-mode-ex.el.

;; haxe-mode is NOT part of GNU Emacs.

;;; Versions:
;;
;;    0.1.0 - Initial release.
;;    0.1.1 - Fixed typedef indentation.
;;            Fixed lexical analysis so that type names can contain digits.
;;    0.2.0 - Base on java-mode instead of c++-mode.
;;            Added compile-error parser for the haXe compiler output.
;;            Loads of improvements.
;;    0.2.1 - Fix buffer-local comment-start-skip problem.
;;

;;; Usage:
;;
;; Include something like this in your .emacs:
;; (require 'haxe-mode)
;; (defconst my-haxe-style
;;   '("java" (c-offsets-alist . ((case-label . +)
;;                                (arglist-intro . +)
;;                                (arglist-cont-nonempty . 0)
;;                                (arglist-close . 0)
;;                                (cpp-macro . 0))))
;;   "My haXe Programming Style")
;; (add-hook 'haxe-mode-hook
;;   (function (lambda () (c-add-style "haxe" my-haxe-style t))))
;; (add-hook 'haxe-mode-hook
;;           (function
;;            (lambda ()
;;              (setq tab-width 4)
;;              (setq indent-tabs-mode t)
;;              (setq fill-column 80)
;;              (local-set-key [(return)] 'newline-and-indent))))

\f
;;; Code:

(require 'cc-mode)
(require 'cc-fonts)
(require 'cc-langs)
(require 'cc-bytecomp)
(require 'compile)

;; The language constants are needed when compiling.
(eval-when-compile
  (let ((load-path
         (if (and (boundp 'byte-compile-dest-file)
                  (stringp byte-compile-dest-file))
             (cons (file-name-directory byte-compile-dest-file) load-path)
           load-path)))
    (load "cc-mode" nil t)
    (load "cc-fonts" nil t)
    (load "cc-langs" nil t)
    (load "cc-bytecomp" nil t)))

(eval-and-compile
  ;; Tell the language constant system about haXe and base it on Java.
  (c-add-language 'haxe-mode 'java-mode))

;;; Lexer-level syntax (identifiers, tokens etc).

;; No other operators in identifiers.
(c-lang-defconst c-after-id-concat-ops
  haxe nil)

;; Conditional compilation prefix.
(c-lang-defconst c-opt-cpp-prefix
  haxe "\\s *#")

;; No strings in conditional compilation.
(c-lang-defconst c-cpp-message-directives
  haxe nil)

;; No file name in angle brackets or quotes in conditional compilation.
(c-lang-defconst c-cpp-include-directives
  haxe nil)

;; No macro definition in conditional compilation.
(c-lang-defconst c-opt-cpp-macro-define
  haxe nil)

;; Conditional compilation directives followed by expressions.
(c-lang-defconst c-cpp-expr-directives
  haxe '("if" "else"))

;; No functions in conditional compilation.
(c-lang-defconst c-cpp-expr-functions
  haxe nil)

;; haXe operators.
(c-lang-defconst c-operators
  haxe `(
         ;; Preprocessor.
         (prefix "#")
         ;; Standard operators.
         ,@(c-lang-const c-identifier-ops)
         ;; Generics.
         (postfix-if-paren "<" ">")
         ;; Postfix.
         (left-assoc "." "->")
         (postfix "++" "--" "[" "]" "(" ")")
         ;; Unary.
         (prefix "++" "--" "+" "-" "!" "~" "new")
         ;; Multiplicative.
         (left-assoc "*" "/" "%")
         ;; Additive.
         (left-assoc "+" "-")
         ;; Shift.
         (left-assoc "<<" ">>" ">>>")
         ;; Relational.
         (left-assoc "<" ">" "<=" ">=")
         ;; Iteration.
         (left-assoc "...")
         ;; Equality.
         (left-assoc "==" "!=" "===" "!==")
         ;; Bitwise and.
         (left-assoc "&")
         ;; Bitwise exclusive or.
         (left-assoc "^")
         ;; Bitwise or.
         (left-assoc "|")
         ;; Logical and.
         (left-assoc "&&")
         ;; Logical or.
         (left-assoc "||")
         ;; Assignment.
         (right-assoc ,@(c-lang-const c-assignment-operators))
         ;; Exception.
         (prefix "throw")
         ;; Sequence.
         (left-assoc ",")))

;; No overloading.
(c-lang-defconst c-overloadable-operators
  haxe nil)
(c-lang-defconst c-opt-op-identitier-prefix
  haxe nil)

;;; Keywords.

;; I will treat types uniformly below since they all start with capital
;; letters.
(c-lang-defconst c-primitive-type-kwds
  haxe nil)

;; TODO: check double occurrence of enum.
;; Type-introduction is straight forward in haXe.
(c-lang-defconst c-class-decl-kwds
  haxe '( "class" "interface" "enum" "typedef" ))

;; Recognises enum constants.
;; TODO: find a way to also recognise parameterised constants.
(c-lang-defconst c-brace-list-decl-kwds
  haxe '( "enum" ))

;; Keywords introducing declarations where the identifier follows directly
;; after the keyword, without any type.
(c-lang-defconst c-typeless-decl-kwds
  haxe (append '( "function" "var" )
               (c-lang-const c-class-decl-kwds)
	       (c-lang-const c-brace-list-decl-kwds)))
  
;; Definition modifiers.
(c-lang-defconst c-modifier-kwds
  haxe '( "private" "public" "static" ))
(c-lang-defconst c-other-decl-kwds
  haxe nil)

;; Namespaces.
(c-lang-defconst c-ref-list-kwds
 haxe '( "import" "package"))

;; Statement keywords followed directly by a substatement.
(c-lang-defconst c-block-stmt-1-kwds
  haxe '( "do" "else" "try" ))

;; Statement keywords followed by a paren sexp and then by a substatement.
(c-lang-defconst c-block-stmt-2-kwds
  haxe '( "for" "if" "switch" "while" "catch" ))

;; Statement keywords followed by an expression or nothing.
(c-lang-defconst c-simple-stmt-kwds
  haxe '( "break" "continue" "return" "default" "new" ))

;; No ';' inside 'for'.
(c-lang-defconst c-paren-stmt-kwds
  haxe nil)

;; Keywords for constants.
(c-lang-defconst c-constant-kwds
  haxe '( "false" "true" "null" ))

;; Keywords for expressions.
(c-lang-defconst c-primary-expr-kwds
  haxe '( "this" "super" ))

(c-lang-defconst c-decl-hangon-kwds
  haxe '( "in" ))

;; No other labels.
(c-lang-defconst c-before-label-kwds
  haxe nil)

;; No classes inside expressions.
(c-lang-defconst c-inexpr-class-kwds
  haxe nil)

;; No brace lists inside expressions.
(c-lang-defconst c-inexpr-brace-list-kwds
  haxe nil)

;; Allow '=' in typedefs so they are treated as classes.
(c-lang-defconst c-block-prefix-disallowed-chars
  haxe (set-difference (c-lang-const c-block-prefix-disallowed-chars java)
                       '(?=)))

;; All identifiers starting with a capital letter are types.
(c-lang-defconst c-cpp-matchers
  haxe (append
        (c-lang-const c-cpp-matchers c)
        '(("\\<\\([A-Z][A-Za-z0-9_]*\\)\\>" 1 font-lock-type-face))))

;; Generic types.
(c-lang-defconst c-recognize-<>-arglists
  haxe t)

;; Fontification degrees.
(defconst haxe-font-lock-keywords-1 (c-lang-const c-matchers-1 haxe)
  "Minimal highlighting for haxe mode.")
(defconst haxe-font-lock-keywords-2 (c-lang-const c-matchers-2 haxe)
  "Fast normal highlighting for haxe mode.")
(defconst haxe-font-lock-keywords-3 (c-lang-const c-matchers-3 haxe)
  "Accurate normal highlighting for haxe mode.")
(defvar haxe-font-lock-keywords haxe-font-lock-keywords-3
  "Default expressions to highlight in haxe mode.")

(defvar haxe-mode-syntax-table nil
  "Syntax table used in HaXe mode buffers.")
(or haxe-mode-syntax-table
    (setq haxe-mode-syntax-table
          (funcall (c-lang-const c-make-mode-syntax-table haxe))))

(defvar haxe-mode-abbrev-table nil
  "Abbreviation table used in haxe mode buffers.")
(c-define-abbrev-table 'haxe-mode-abbrev-table
  ;; Keywords that, if they occur first on a line, might alter the
  ;; syntactic context, and which therefore should trigger
  ;; reindentation when they are completed.
  '(("else" "else" c-electric-continued-statement 0)
    ("while" "while" c-electric-continued-statement 0)
    ("catch" "catch" c-electric-continued-statement 0)))

(defvar haxe-mode-map ()
  "Keymap used in haxe mode buffers.")
(if haxe-mode-map
    nil
  (setq haxe-mode-map (c-make-inherited-keymap)))

(add-to-list 'auto-mode-alist '("\\.hx\\'" . haxe-mode))

;; Tell compilation-mode how to parse error messages.  You need to set
;; compilation-error-screen-columns to nil to get the right
;; interpretation of tabs.
(add-to-list 'compilation-error-regexp-alist
             '("^\\([^: ]+\\):\\([0-9]+\\): characters \\([0-9]+\\)-[0-9]+ : "
               1 2 3))

(defcustom haxe-mode-hook nil
  "*Hook called by `haxe-mode'."
  :type 'hook
  :group 'c)

(defun haxe-mode ()
  "Major mode for editing haXe code.

The hook `c-mode-common-hook' is run with no args at mode
initialization, then `haxe-mode-hook'.

Key bindings:
\\{haxe-mode-map}"
  (interactive)
  (kill-all-local-variables)
  (c-initialize-cc-mode t)
  (set-syntax-table haxe-mode-syntax-table)
  (setq major-mode 'haxe-mode
        mode-name "haXe"
        local-abbrev-table haxe-mode-abbrev-table
        abbrev-mode t)
  (use-local-map haxe-mode-map)
  ;; `c-init-language-vars' is a macro that is expanded at compile
  ;; time to a large `setq' with all the language variables and their
  ;; customized values for our language.
  (c-init-language-vars haxe-mode)
  ;; `c-common-init' initializes most of the components of a CC Mode
  ;; buffer, including setup of the mode menu, font-lock, etc.
  ;; There's also a lower level routine `c-basic-common-init' that
  ;; only makes the necessary initialization to get the syntactic
  ;; analysis and similar things working.
  (c-common-init 'haxe-mode)
  ;; For some reason, comment-start-skip has to be set manually.
  (setq comment-start-skip "\\(//+\\|/\\*+\\)\\s *")
  ;; TODO: (easy-menu-add haxe-menu)
  (run-hooks 'c-mode-common-hook 'haxe-mode-hook)
  (c-update-modeline))

(provide 'haxe-mode)

;;; haxe-mode.el ends here.

[-- Attachment #3: test.hx --]
[-- Type: text/plain, Size: 1302 bytes --]

package my.pack;

/**
 * Class typedef.
 */
class Foo
	extends Base,
	implements ITest< Int >
{
	private var i : Int;
	public function new() {
		this.i = null;
	}
	public static function foo( x ) {
		x = 1;
	}
}

enum Bar< T > {
	ost;
	quux( t : T );
}

/**
 * Test typedef.
 */
typedef Pack = {
	var int : Int;	
}
	
interface Quux {  // <== Indentation
	var i;
}

/**
 * Test enum.
 */
typedef Num = Int;

// $Test @class.
class Test extends Base, implements ITest< Int > {
	static var x = lib.foo;
	#if flash
	static var y = lib.foo();
	static var z : Foo = new Foo();
	#end
	for( i in 1...10 ) {
		trace( 'i=' + i );
	}
	var regex = ~/[A-Z0-9._%-]+@[A-Z0-9.-]+\.[A-Z][A-Z][A-Z]?/i;
	return {
		width : width + attribControlWith,
		growWidth : true
	};
}
  
class InsertIv
	extends ActionBase,
	implements IAction< How >
{
	private var dummy( default, null ) =
		[ new CheckBreathing()
		, new Headtilt()
		, new InsertIv()
		];
	var x = [
		new Foo(),
		new Bar()
	];
	public function deriveAttributes(
		ds : ActionDescription,
		start : Bool
	) :
		Link< Ost >
	{
		var f = function( x ) {
			return x;
		};
		var g
			= function() {
			c = 1;  // <== Indentation
		}  // <== Indentation
		switch( x ) {
			case 1:
				x = 3.4;
				y = "Ost";
			case 2: {
				x += 1;
				y += "en";
			}
		}
	}
}

[-- Attachment #4: Type: text/plain, Size: 142 bytes --]

_______________________________________________
Emacs-devel mailing list
Emacs-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/emacs-devel

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: New major mode using cc-mode => cc-mode intrudes unrelated modes
  2007-06-27 19:28 New major mode using cc-mode => cc-mode intrudes unrelated modes Jens Peter Secher
@ 2007-06-29 16:22 ` Vagn Johansen
  2007-07-16 22:42 ` Alan Mackenzie
  1 sibling, 0 replies; 5+ messages in thread
From: Vagn Johansen @ 2007-06-29 16:22 UTC (permalink / raw)
  To: emacs-devel

Jens Peter Secher <jpsecher@gmail.com> writes:

> The problems is that, efter putting a buffer in haxe-mode, cc-mode
> functions intrude into others modes, eg. lisp-mode.  More specifically,
> after visiting the haxe-mode test file in the second attachment, a newly
> created lisp-mode buffer will have eg. beginning-of-defun-function set
> to c-beginning-of-defun.

I encounter the same problem with csharp-mode (moonfire version 0.6.0)
and action script mode (http://blog.pettomato.com/?p=24).

After opening a cs or as3 file and then opening an .el file I then get
errors on most lisp related command (TAB, C-M-A) etc. e.g. TAB gives

Debugger entered--Lisp error: (wrong-type-argument stringp nil)
  looking-at(nil)
  c-backward-sws()
  c-beginning-of-statement-1(nil nil t)
  byte-code(<snip>
  c-beginning-of-decl-1(nil)
  c-where-wrt-brace-construct()
  c-beginning-of-defun()
  beginning-of-defun-raw(nil)
  beginning-of-defun()
  calculate-lisp-indent()
  lisp-indent-line(nil)
  call-interactively(lisp-indent-line)


I get "improved" behaviour if I have the following in my .emacs

  (make-variable-buffer-local 'beginning-of-defun-function)
  (make-variable-buffer-local 'end-of-defun-function)

But I have only tried this for 10 minutes.

-- 

Vagn Johansen

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: New major mode using cc-mode => cc-mode intrudes unrelated modes
  2007-06-27 19:28 New major mode using cc-mode => cc-mode intrudes unrelated modes Jens Peter Secher
  2007-06-29 16:22 ` Vagn Johansen
@ 2007-07-16 22:42 ` Alan Mackenzie
  2007-07-17 15:05   ` Richard Stallman
  2007-07-17 16:14   ` Jens Peter Secher
  1 sibling, 2 replies; 5+ messages in thread
From: Alan Mackenzie @ 2007-07-16 22:42 UTC (permalink / raw)
  To: Jens Peter Secher; +Cc: Vagn Johansen, Richard Stallman, emacs-devel

Hi, Jens.

On Wed, Jun 27, 2007 at 09:28:06PM +0200, Jens Peter Secher wrote:
> I have been trying to create a major mode for a programming language
> called haXe, but I have run into problems.  haxe-mode is basically just
> a cut-down version of java-mode, as you can see from the first attached
> file.

A quick observation here: I think you will need to make your file GPL
licensed before you release it, since it will be a derivative of Emacs, a
GPL program.  But RMS is the expert on this.

> The problems is that, efter putting a buffer in haxe-mode, cc-mode
> functions intrude into others modes, eg. lisp-mode.  More specifically,
> after visiting the haxe-mode test file in the second attachment, a newly
> created lisp-mode buffer will have eg. beginning-of-defun-function set
> to c-beginning-of-defun.

> Another strange thing is that I have to set comment-start-skip
> explicitly in haxe-mode, otherwise it gets a nil value when visiting
> haxe-mode files.

> So obviously I am doing something wrong, but I cannot figure out what.

No, on the contrary, I've done something wrong.  ;-)  There's a macro
c-make-emacs-variables-local, which does what its name says on the five
variables: comment-start, comment-end, comment-start-skip,
beginning-of-defun-function, and end-of-defun-function.  I had put this
macro call in a position which worked only for C, C++, ...., Pike, AWK,
but not for derived modes.

> I am using Emacs 22.0.99.1 (including cc-mode 5.31.4).

Would you please try this patch out, and let me know whether it fixes
everything.  Thanks for taking the trouble to report this bug, and thanks
for making it so easy for me to track down.


2007-07-16  Alan Mackenzie  <acm@muc.de>

	* progmodes/cc-mode.el (c-init-language-vars-for):
	* progmodes/cc-langs.el (c-make-init-lang-vars-fun): Move the
	invocation of c-make-emacs-variables-local from the former
	function to the latter, because derived modes bypass the former.


Index: cc-mode.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/progmodes/cc-mode.el,v
retrieving revision 1.58.2.2
diff -c -r1.58.2.2 cc-mode.el
*** cc-mode.el	20 Jun 2007 08:27:53 -0000	1.58.2.2
--- cc-mode.el	16 Jul 2007 20:50:17 -0000
***************
*** 168,174 ****
  `c-init-language-vars' macro if the language you want to use is one of
  those, rather than a derived language defined through the language
  variable system (see \"cc-langs.el\")."
-   (c-make-emacs-variables-local)
    (cond ((eq mode 'c-mode)    (c-init-language-vars c-mode))
  	((eq mode 'c++-mode)  (c-init-language-vars c++-mode))
  	((eq mode 'objc-mode) (c-init-language-vars objc-mode))
--- 168,173 ----
Index: cc-langs.el
===================================================================
RCS file: /cvsroot/emacs/emacs/lisp/progmodes/cc-langs.el,v
retrieving revision 1.47
diff -c -r1.47 cc-langs.el
*** cc-langs.el	9 Apr 2007 10:51:29 -0000	1.47
--- cc-langs.el	16 Jul 2007 20:50:29 -0000
***************
*** 2898,2903 ****
--- 2898,2904 ----
  	 ;; that could be in the result from `cl-macroexpand-all'.
  	 (let ((c-buffer-is-cc-mode ',mode)
  	       current-var source-eval)
+ 	   (c-make-emacs-variables-local)
  	   (condition-case err
  
  	       (if (eq c-version-sym ',c-version-sym)
***************
*** 2956,2961 ****
--- 2957,2963 ----
  	     (init (append (cdr c-emacs-variable-inits)
  			   (cdr c-lang-variable-inits)))
  	     current-var)
+ 	 (c-make-emacs-variables-local)
  	 (condition-case err
  
  	     (while init



> Cheers,
> -- 
>                                                     Jens Peter Secher.

-- 
Alan Mackenzie (Ittersbach, Germany).

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: New major mode using cc-mode => cc-mode intrudes unrelated modes
  2007-07-16 22:42 ` Alan Mackenzie
@ 2007-07-17 15:05   ` Richard Stallman
  2007-07-17 16:14   ` Jens Peter Secher
  1 sibling, 0 replies; 5+ messages in thread
From: Richard Stallman @ 2007-07-17 15:05 UTC (permalink / raw)
  To: Alan Mackenzie; +Cc: gonz808, emacs-devel, jpsecher

    A quick observation here: I think you will need to make your file GPL
    licensed before you release it, since it will be a derivative of Emacs, a
    GPL program.  But RMS is the expert on this.

Yes.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: New major mode using cc-mode => cc-mode intrudes unrelated modes
  2007-07-16 22:42 ` Alan Mackenzie
  2007-07-17 15:05   ` Richard Stallman
@ 2007-07-17 16:14   ` Jens Peter Secher
  1 sibling, 0 replies; 5+ messages in thread
From: Jens Peter Secher @ 2007-07-17 16:14 UTC (permalink / raw)
  To: emacs-devel

On 17/07/07, Alan Mackenzie <acm@muc.de> wrote:
>
> On Wed, Jun 27, 2007 at 09:28:06PM +0200, Jens Peter Secher wrote:
> > I have been trying to create a major mode for a programming language
> > called haXe, but I have run into problems.  haxe-mode is basically just
> > a cut-down version of java-mode, as you can see from the first attached
> > file.
>
> A quick observation here: I think you will need to make your file GPL
> licensed before you release it, since it will be a derivative of Emacs, a
> GPL program.  But RMS is the expert on this.

You're right, I'll make it GPL3 then.

> Would you please try this patch out, and let me know whether it fixes
> everything.  Thanks for taking the trouble to report this bug, and thanks
> for making it so easy for me to track down.

Thanks for the patch, it resolves the problem.

Cheers,
-- 
                                                    Jens Peter Secher.
_DD6A 05B0 174E BFB2 D4D9 B52E 0EE5 978A FE63 E8A1 jpsecher gmail com_.
A. Because it breaks the logical sequence of discussion.
Q. Why is top posting bad?

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2007-07-17 16:14 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-27 19:28 New major mode using cc-mode => cc-mode intrudes unrelated modes Jens Peter Secher
2007-06-29 16:22 ` Vagn Johansen
2007-07-16 22:42 ` Alan Mackenzie
2007-07-17 15:05   ` Richard Stallman
2007-07-17 16:14   ` Jens Peter Secher

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).