'((c-mode . 1) (c++-mode . 1)))
@end example
-@cindex incorrect fontification
-@cindex parenthesis in column zero and fontification
-@cindex brace in column zero and fontification
- Comment and string fontification (or ``syntactic'' fontification)
-relies on analysis of the syntactic structure of the buffer text. For
-the sake of speed, some modes, including Lisp mode, rely on a special
-convention: an open-parenthesis or open-brace in the leftmost column
-always defines the beginning of a defun, and is thus always outside
-any string or comment. Therefore, you should avoid placing an
-open-parenthesis or open-brace in the leftmost column, if it is inside
-a string or comment. @xref{Left Margin Paren}, for details.
-
@findex font-lock-add-keywords
Font Lock highlighting patterns already exist for most modes, but
you may want to fontify additional patterns. You can use the function
Top-Level Definitions, or Defuns
-* Left Margin Paren:: An open-paren or similar opening delimiter
- starts a defun if it is at the left margin.
* Moving by Defuns:: Commands to move over or mark a major definition.
* Imenu:: Making buffer indexes as menus.
* Which Function:: Which Function mode shows which function you are in.
Emacs we use it for all languages.
@menu
-* Left Margin Paren:: An open-paren or similar opening delimiter
- starts a defun if it is at the left margin.
* Moving by Defuns:: Commands to move over or mark a major definition.
* Moving by Sentences:: Commands to move over certain code units.
* Imenu:: Making buffer indexes as menus.
* Which Function:: Which Function mode shows which function you are in.
@end menu
-@node Left Margin Paren
-@subsection Left Margin Convention
-
-@cindex open-parenthesis in leftmost column
-@cindex ( in leftmost column
- Many programming-language modes have traditionally assumed that any
-opening parenthesis or brace found at the left margin is the start of
-a top-level definition, or defun. So, by default, commands which seek
-the beginning of a defun accept such a delimiter as signifying that
-position.
-
-@vindex open-paren-in-column-0-is-defun-start
- If you want to override this convention, you can do so by setting
-the user option @code{open-paren-in-column-0-is-defun-start} to
-@code{nil}. If this option is set to @code{t} (the default), commands
-seeking the start of a defun will stop at opening parentheses or
-braces at column zero which aren't in a comment or string. When it is
-@code{nil}, defuns are found by searching for parens or braces at the
-outermost level. Since low-level Emacs routines no longer depend on
-this convention, you usually won't need to change
-@code{open-paren-in-column-0-is-defun-start} from its default.
-
@node Moving by Defuns
@subsection Moving by Defuns
@cindex defuns
manually give one of these lines a nonstandard indentation (e.g., for
aesthetic purposes), the lines below will follow it.
- The indentation commands for most programming language modes assume
-that an open-parenthesis, open-brace or other opening delimiter at the
-left margin is the start of a function. If the code you are editing
-violates this assumption---even if the delimiters occur in strings or
-comments---you must set @code{open-paren-in-column-0-is-defun-start}
-to @code{nil} for indentation to work properly. @xref{Left Margin
-Paren}.
-
@node Multi-line Indent
@subsection Indenting Several Lines
followed by a character with open-parenthesis syntax.
@end defopt
-@cindex \( in strings
-@defopt open-paren-in-column-0-is-defun-start
-If this variable's value is non-@code{nil}, an open parenthesis in
-column 0 is considered to be the start of a defun. If it is
-@code{nil}, an open parenthesis in column 0 has no special meaning.
-The default is @code{t}. If a string literal happens to have a
-parenthesis in column 0, escape it with a backslash to avoid a false
-positive.
-@end defopt
-
@defvar beginning-of-defun-function
If non-@code{nil}, this variable holds a function for finding the
beginning of a defun. The function @code{beginning-of-defun}
(setq c-offsets-alist '((substatement-open . 0)))
@end example
-@item
-@cindex open paren in column zero
-@emph{I have an open paren character at column zero inside a comment or
-multiline string literal, and it causes the fontification and/or
-indentation to go haywire. What gives?}
-
-It's due to the ad-hoc rule in (X)Emacs that such open parens always
-start defuns (which translates to functions, classes, namespaces or any
-other top-level block constructs in the @ccmode{} languages).
-@ifset XEMACS
-@xref{Defuns,,, xemacs, XEmacs User's Manual}, for details.
-@end ifset
-@ifclear XEMACS
-@xref{Left Margin Paren,,, emacs, GNU Emacs Manual}, for details
-(@xref{Defuns,,, emacs, GNU Emacs Manual}, in the Emacs 20 manual).
-@end ifclear
-
-This heuristic is built into the core syntax analysis routines in
-(X)Emacs, so it's not really a @ccmode{} issue. However, in Emacs
-21.1 it became possible to turn it off@footnote{Using the variable
-@code{open-paren-in-column-0-is-defun-start}.} and @ccmode{} does so
-there since it's got its own system to keep track of blocks.
-
@end itemize
;; syntax.c
(parse-sexp-ignore-comments editing-basics boolean)
(words-include-escapes editing-basics boolean)
- (open-paren-in-column-0-is-defun-start editing-basics boolean
- "21.1")
;; term.c
(visible-cursor cursor boolean "22.1")
;; terminal.c
((eq prop :tag)
(put symbol 'custom-tag propval))))))))
-(custom-add-to-group 'font-lock 'open-paren-in-column-0-is-defun-start
- 'custom-variable)
-
;; Record cus-start as loaded if we have set up all the info that we can.
;; Don't record it as loaded if we have only set up the standard values
;; and safe/risky properties.
:version "28.1")
;;;###autoload(put 'checkdoc-symbol-words 'safe-local-variable #'list-of-strings-p)
-(defcustom checkdoc-column-zero-backslash-before-paren t
- "Non-nil means to warn if there is no \"\\\" before \"(\" in column zero.
-This backslash is no longer needed on Emacs 27.1 or later.
-
-See Info node `(elisp) Documentation Tips' for background."
- :type 'boolean
- :version "28.1")
-
;; This is how you can use checkdoc to make mass fixes on the Emacs
;; source tree:
;;
`("Remove indentation"
((,(current-buffer)
(,(match-beginning 1) ,(match-end 1) ""))))))))
- ;; * Check for '(' in column 0.
- (when checkdoc-column-zero-backslash-before-paren
- (save-excursion
- (when (re-search-forward "^(" e t)
- (if (checkdoc-autofix-ask-replace (match-beginning 0)
- (match-end 0)
- (format-message "Escape this `('?")
- "\\(")
- nil
- (checkdoc-create-error
- "Open parenthesis in column 0 should be escaped"
- (match-beginning 0) (match-end 0)
- `("Escape parenthesis in column 0"
- ((,(current-buffer)
- (,(match-beginning 0) ,(match-beginning 0) "\\")))))))))
;; * Do not start or end a documentation string with whitespace.
(let (start end)
(if (or (if (looking-at "\"\\([ \t\n]+\\)")
(defmacro let-when-compile (bindings &rest body)
"Like `let*', but allow for compile time optimization.
-Use BINDINGS as in regular `let*', but in BODY each usage should
+Use BINDINGS as in regular `let*', but in \BODY each usage should
be wrapped in `eval-when-compile'.
This will generate compile-time constants from BINDINGS."
(declare (indent 1) (debug let))
(let* ((beg0 (match-beginning 0))
(end0 (match-end 0))
(ppss (save-excursion (syntax-ppss beg0))))
- (and (nth 3 ppss) ;Inside a string.
- (not (nth 5 ppss)) ;The \ is not itself \-escaped.
- ;; Don't highlight the \( introduced because of
- ;; `open-paren-in-column-0-is-defun-start'.
- (not (eq ?\n (char-before beg0)))
+ (and (nth 3 ppss) ;Inside a string.
+ (not (nth 5 ppss)) ;The \ is not itself \-escaped.
(equal (ignore-errors
(car (read-from-string
(format "\"%s\""
If search is successful, return t; point ends up at the beginning
of the line where the search succeeded. Otherwise, return nil.
-When `open-paren-in-column-0-is-defun-start' is non-nil, a defun
-is assumed to start where there is a char with open-parenthesis
-syntax at the beginning of a line. If `defun-prompt-regexp' is
-non-nil, then a string which matches that regexp may also precede
-the open-parenthesis. If `defun-prompt-regexp' and
-`open-paren-in-column-0-is-defun-start' are both nil, this
-function instead finds an open-paren at the outermost level.
+If `defun-prompt-regexp' is non-nil, then a string which matches that
+regexp may also precede the open-parenthesis. Otherwise, this function
+instead finds an open-paren at the outermost level.
If the variable `beginning-of-defun-function' is non-nil, its
value is called as a function, with argument ARG, to find the
(dotimes (_ (- arg))
(funcall end-of-defun-function))))))
- ((or defun-prompt-regexp open-paren-in-column-0-is-defun-start)
+ (defun-prompt-regexp
(and (< arg 0) (not (eobp)) (forward-char 1))
(and (let (found)
(while
(and (setq found
(re-search-backward
(if defun-prompt-regexp
- (concat (if open-paren-in-column-0-is-defun-start
- "^\\s(\\|" "")
- "\\(?:" defun-prompt-regexp "\\)\\s(")
+ (concat "\\(?:" defun-prompt-regexp "\\)\\s(")
"^\\s(")
nil 'move arg))
(save-match-data
(progn (goto-char (1- (match-end 0)))
t)))
- ;; If open-paren-in-column-0-is-defun-start and defun-prompt-regexp
- ;; are both nil, column 0 has no significance - so scan forward
- ;; from BOB to see how nested point is, then carry on from there.
+ ;; If defun-prompt-regexp is nil, column 0 has no significance - so
+ ;; scan forward from BOB to see how nested point is, then carry on
+ ;; from there.
;;
;; It is generally not a good idea to land up here, because the
;; call to scan-lists below can be extremely slow. This is because
(let* ((beg (scope-sym-pos sym))
(bare (bare-symbol sym))
(len (length (symbol-name bare))))
- (unless (or (booleanp bare) (keywordp bare) (null beg))
- (funcall scope-callback 'variable beg len (scope-local-get bare local)))))
+ (when (and beg (not (booleanp bare)))
+ (if (keywordp bare)
+ (funcall scope-callback 'constant beg len nil)
+ (funcall scope-callback 'variable beg len (scope-local-get bare local))))))
(defun scope-let-1 (local0 local bindings body)
(if bindings
nil))
(scope-n local forms))
((special-form-p bare)
+ (when (symbol-with-pos-p f)
+ (funcall scope-callback 'special-form
+ (symbol-with-pos-pos f) (length (symbol-name bare))
+ nil))
(cond
((eq bare 'let)
(scope-let local (car forms) (cdr forms)))
progn prog1))
(scope-n local forms))))
((macrop bare)
+ (when (symbol-with-pos-p f)
+ (funcall scope-callback 'macro
+ (symbol-with-pos-pos f) (length (symbol-name bare))
+ nil))
(cond
((eq (get bare 'edebug-form-spec) t) (scope-n local forms))
((eq bare 'lambda) (scope-lambda local (car forms) (cdr forms)))
((memq bare '(declare-function))
(scope-declare-function local (car forms) (cadr forms)
(caddr forms) (cadddr forms)))
- ((memq bare '(let-when-compile))
- (scope-let* local (car forms) (cdr forms)))
((memq bare '(setq-local setq-default))
(scope-setq local forms))
((memq bare '(cl-block))
(scope-return-from local (car forms) (cadr forms)))
((memq bare '(rx)) ; `rx' is unsafe, never expand!
(scope-rx local forms))
+ ((memq bare '(let-when-compile)) ; `let-when-compile' too!
+ (scope-let* local (car forms) (cdr forms)))
((memq bare '(cl-eval-when)) ; Likewise!
(scope-rx local (cdr forms)))
((scope-safe-macro-p bare)
;; buffer local variable, which is computed depending on remote host properties
;; when `tramp-chunksize' is zero or nil.
(defcustom tramp-chunksize (when (memq system-type '(hpux)) 500)
-;; Parentheses in docstring starting at beginning of line are escaped.
-;; Fontification is messed up when
-;; `open-paren-in-column-0-is-defun-start' set to t.
"If non-nil, chunksize for sending input to local process.
It is necessary only on systems which have a buggy `process-send-string'
implementation. The necessity, whether this variable must be set, can be
\f
;; Figure out what features this Emacs has
-(cc-bytecomp-defvar open-paren-in-column-0-is-defun-start)
-
(defconst c-emacs-features
(let (list)
(= (skip-chars-forward "[:alpha:]") 3))
(setq list (cons 'posix-char-classes list)))
- ;; See if `open-paren-in-column-0-is-defun-start' exists and
- ;; isn't buggy (Emacs >= 21.4).
- (when (boundp 'open-paren-in-column-0-is-defun-start)
- (let ((open-paren-in-column-0-is-defun-start nil)
- (parse-sexp-ignore-comments t))
- (delete-region (point-min) (point-max))
- (set-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\' "\"")
- (cond
- ;; XEmacs. Afaik this is currently an Emacs-only
- ;; feature, but it's good to be prepared.
- ((memq '8-bit list)
- (modify-syntax-entry ?/ ". 1456")
- (modify-syntax-entry ?* ". 23"))
- ;; Emacs
- ((memq '1-bit list)
- (modify-syntax-entry ?/ ". 124b")
- (modify-syntax-entry ?* ". 23")))
- (modify-syntax-entry ?\n "> b")
- (insert "/* '\n () */")
- (backward-sexp)
- (if (bobp)
- (setq list (cons 'col-0-paren list)))))
+ (let ((parse-sexp-ignore-comments t))
+ (delete-region (point-min) (point-max))
+ (set-syntax-table (make-syntax-table))
+ (modify-syntax-entry ?\' "\"")
+ (cond
+ ;; XEmacs. Afaik this is currently an Emacs-only
+ ;; feature, but it's good to be prepared.
+ ((memq '8-bit list)
+ (modify-syntax-entry ?/ ". 1456")
+ (modify-syntax-entry ?* ". 23"))
+ ;; Emacs
+ ((memq '1-bit list)
+ (modify-syntax-entry ?/ ". 124b")
+ (modify-syntax-entry ?* ". 23")))
+ (modify-syntax-entry ?\n "> b")
+ (insert "/* '\n () */")
+ (backward-sexp)
+ (if (bobp)
+ (setq list (cons 'col-0-paren list))))
(set-buffer-modified-p nil))
(kill-buffer buf)))
;; instead? This heuristic no longer works well in C++, where
;; declarations inside namespace brace blocks are frequently placed at
;; column zero. (2015-11-10): Remove the condition on C++ Mode.
- (when (and (or (not (memq 'col-0-paren c-emacs-features))
- open-paren-in-column-0-is-defun-start)
+ (when (and (not (memq 'col-0-paren c-emacs-features))
;; (not (c-major-mode-is 'c++-mode))
(> how-far c-state-cache-too-far))
(setq BOD-pos (c-get-fallback-scan-pos here)) ; somewhat EXPENSIVE!!!
(cons `(,tprop . t) text-property-default-nonsticky))))
'(syntax-table c-fl-syn-tab category c-type)))
- ;; In Emacs 21 and later it's possible to turn off the ad-hoc
- ;; heuristic that open parens in column 0 are defun starters. Since
- ;; we have c-state-cache, that heuristic isn't useful and only causes
- ;; trouble, so turn it off.
-;; 2006/12/17: This facility is somewhat confused, and doesn't really seem
-;; helpful. Comment it out for now.
-;; (when (memq 'col-0-paren c-emacs-features)
-;; (make-local-variable 'open-paren-in-column-0-is-defun-start)
-;; (setq open-paren-in-column-0-is-defun-start nil))
-
(c-clear-found-types)
;; now set the mode style based on default-style
(if (cperl-val 'cperl-electric-keywords)
(abbrev-mode 1))
(set-syntax-table cperl-mode-syntax-table)
- ;; Workaround for Bug#30393, needed for Emacs 26.
- (when (< emacs-major-version 27)
- (setq-local open-paren-in-column-0-is-defun-start nil))
;; Until Emacs is multi-threaded, we do not actually need it local:
(make-local-variable 'cperl-font-locking)
(setq-local outline-regexp cperl-outline-regexp)
"Elisp-Byte-Code"
"Major mode for *.elc files."
;; TODO: Add way to disassemble byte-code under point.
- (setq-local open-paren-in-column-0-is-defun-start nil)
(setq-local syntax-propertize-function
#'elisp-byte-code-syntax-propertize))
(setq-local indent-line-function #'js-indent-line)
(setq-local beginning-of-defun-function #'js-beginning-of-defun)
(setq-local end-of-defun-function #'js-end-of-defun)
- (setq-local open-paren-in-column-0-is-defun-start nil)
(setq-local font-lock-defaults
(list js--font-lock-keywords nil nil nil nil
'(font-lock-syntactic-face-function
(make-obsolete-variable 'load-dangerous-libraries
"no longer used." "27.1")
+(defvar comment-use-syntax-ppss nil "Unused obsolete variable.")
+(make-obsolete-variable 'comment-use-syntax-ppss nil "31.1")
+
+(defvar open-paren-in-column-0-is-defun-start nil "Unused obsolete variable.")
+(make-obsolete-variable 'open-paren-in-column-0-is-defun-start nil "31.1")
+
(define-obsolete-function-alias 'compare-window-configurations
#'window-configuration-equal-p "29.1")
/* Return a defun-start position before POS and not too far before.
It should be the last one before POS, or nearly the last.
- When open_paren_in_column_0_is_defun_start is nonzero,
- only the beginning of the buffer is treated as a defun-start.
-
We record the information about where the scan started
and what its result was, so that another call in the same area
can return the same value very quickly.
&& MODIFF == find_start_modiff)
return find_start_value;
- if (!NILP (Vcomment_use_syntax_ppss))
- {
- modiff_count modiffs = CHARS_MODIFF;
- Lisp_Object ppss = call1 (Qsyntax_ppss, make_fixnum (pos));
- if (modiffs != CHARS_MODIFF)
- error ("syntax-ppss modified the buffer!");
- TEMP_SET_PT_BOTH (opoint, opoint_byte);
- Lisp_Object boc = Fnth (make_fixnum (8), ppss);
- if (FIXNUMP (boc))
- {
- find_start_value = XFIXNUM (boc);
- find_start_value_byte = CHAR_TO_BYTE (find_start_value);
- }
- else
- {
- find_start_value = pos;
- find_start_value_byte = pos_byte;
- }
- goto found;
- }
- if (!open_paren_in_column_0_is_defun_start)
+ modiff_count modiffs = CHARS_MODIFF;
+ Lisp_Object ppss = call1 (Qsyntax_ppss, make_fixnum (pos));
+ if (modiffs != CHARS_MODIFF)
+ error ("syntax-ppss modified the buffer!");
+ TEMP_SET_PT_BOTH (opoint, opoint_byte);
+ Lisp_Object boc = Fnth (make_fixnum (8), ppss);
+ if (FIXNUMP (boc))
{
- find_start_value = BEGV;
- find_start_value_byte = BEGV_BYTE;
- goto found;
+ find_start_value = XFIXNUM (boc);
+ find_start_value_byte = CHAR_TO_BYTE (find_start_value);
}
-
- /* Back up to start of line. */
- scan_newline (pos, pos_byte, BEGV, BEGV_BYTE, -1, 1);
-
- /* We optimize syntax-table lookup for rare updates. Thus we accept
- only those `^\s(' which are good in global _and_ text-property
- syntax-tables. */
- SETUP_BUFFER_SYNTAX_TABLE ();
- while (PT > BEGV)
+ else
{
- /* Open-paren at start of line means we may have found our
- defun-start. */
- int c = FETCH_CHAR_AS_MULTIBYTE (PT_BYTE);
- if (SYNTAX (c) == Sopen)
- {
- SETUP_SYNTAX_TABLE (PT + 1, -1); /* Try again... */
- c = FETCH_CHAR_AS_MULTIBYTE (PT_BYTE);
- if (SYNTAX (c) == Sopen)
- break;
- /* Now fallback to the default value. */
- SETUP_BUFFER_SYNTAX_TABLE ();
- }
- /* Move to beg of previous line. */
- scan_newline (PT, PT_BYTE, BEGV, BEGV_BYTE, -2, 1);
+ find_start_value = pos;
+ find_start_value_byte = pos_byte;
}
- /* Record what we found, for the next try. */
- find_start_value = PT;
- find_start_value_byte = PT_BYTE;
- TEMP_SET_PT_BOTH (opoint, opoint_byte);
-
- found:
find_start_buffer = current_buffer;
find_start_modiff = MODIFF;
find_start_begv = BEGV;
{
rarely_quit (++quit_count);
- ptrdiff_t temp_byte;
int prev_syntax;
bool com2start, com2end, comstart;
comment_lossage = 1;
break;
- case Sopen:
- /* Assume a defun-start point is outside of strings. */
- if (open_paren_in_column_0_is_defun_start
- && NILP (Vcomment_use_syntax_ppss)
- && (from == stop
- || (temp_byte = dec_bytepos (from_byte),
- FETCH_CHAR (temp_byte) == '\n')))
- {
- defun_start = from;
- defun_start_byte = from_byte;
- from = stop; /* Break out of the loop. */
- }
- break;
-
default:
break;
}
{
DEFSYM (Qsyntax_table_p, "syntax-table-p");
DEFSYM (Qsyntax_ppss, "syntax-ppss");
- DEFVAR_LISP ("comment-use-syntax-ppss",
- Vcomment_use_syntax_ppss,
- doc: /* Non-nil means `forward-comment' can use `syntax-ppss' internally. */);
- Vcomment_use_syntax_ppss = Qt;
staticpro (&Vsyntax_code_object);
doc: /* Non-nil means `scan-sexps' treats all multibyte characters as symbol. */);
multibyte_syntax_as_symbol = 0;
- DEFVAR_BOOL ("open-paren-in-column-0-is-defun-start",
- open_paren_in_column_0_is_defun_start,
- doc: /* Non-nil means an open paren in column 0 denotes the start of a defun. */);
- open_paren_in_column_0_is_defun_start = 1;
-
-
DEFVAR_LISP ("find-word-boundary-function-table",
Vfind_word_boundary_function_table,
doc: /*