all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
blob 33abb6d92cb0b084a536436307cfa528af5bde90 8258 bytes (raw)
name: lisp/progmodes/prog-mode.el 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
 
;;; prog-mode.el --- Generic major mode for programming  -*- lexical-binding: t -*-

;; Copyright (C) 2013-2015 Free Software Foundation, Inc.

;; Maintainer: emacs-devel@gnu.org
;; Keywords: internal
;; Package: emacs

;; This file is part of GNU Emacs.

;; GNU Emacs 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 3 of the License, or
;; (at your option) any later version.

;; GNU Emacs 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.  If not, see <http://www.gnu.org/licenses/>.

;;; Commentary:

;; This major mode is mostly intended as a parent of other programming
;; modes.  All major modes for programming languages should derive from this
;; mode so that users can put generic customization on prog-mode-hook.

;;; Code:

(eval-when-compile (require 'cl-lib))

(defgroup prog-mode nil
  "Generic programming mode, from which others derive."
  :group 'languages)

(defcustom prog-mode-hook nil
  "Normal hook run when entering programming modes."
  :type 'hook
  :options '(flyspell-prog-mode abbrev-mode flymake-mode linum-mode
                                prettify-symbols-mode)
  :group 'prog-mode)

(defvar prog-mode-map
  (let ((map (make-sparse-keymap)))
    (define-key map [?\C-\M-q] 'prog-indent-sexp)
    map)
  "Keymap used for programming modes.")

(defvar prog-indentation-context nil
  "Non-nil while indenting embedded code chunks.
There are languages where part of the code is actually written in
a sub language, e.g., a Yacc/Bison or ANTLR grammar also consists
of plain C code.  This variable enables the major mode of the
main language to use the indentation engine of the sub mode for
lines in code chunks written in the sub language.

When a major mode of such a main language decides to delegate the
indentation of a line/region to the indentation engine of the sub
mode, it is supposed to bind this variable to non-nil around the call.

The non-nil value looks as follows
   \(FIRST-COLUMN (START . END) PREVIOUS-CHUNKS)

FIRST-COLUMN is the column the indentation engine of the sub mode
should usually choose for top-level language constructs inside
the code chunk (instead of 0).

START to END is the region of the code chunk.  See function
`prog-widen' for additional info.

PREVIOUS-CHUNKS, if non-nil, provides the indentation engine of
the sub mode with the virtual context of the code chunk.  Valid
values are:

 - A string containing code which the indentation engine can
   consider as standing in front of the code chunk.  For example,
   it can contain a function header to make the code chunk
   being correctly indented as a function body.

 - A function called with the start position of the current
   chunk.  It will return either the region of the previous chunk
   as \(PREV-START . PREV-END) or nil if there is no further
   previous chunk.")


(defun prog-indent-sexp (&optional defun)
  "Indent the expression after point.
When interactively called with prefix, indent the enclosing defun
instead."
  (interactive "P")
  (save-excursion
    (when defun
      (end-of-line)
      (beginning-of-defun))
    (let ((start (point))
	  (end (progn (forward-sexp 1) (point))))
      (indent-region start end nil))))

(defun prog-first-column ()
  "Return the indentation column normally used for top-level constructs."
  (or (car prog-indentation-context) 0))

(defun prog-widen ()
  "Remove restrictions (narrowing) from current code chunk or buffer.
This function should be used instead of `widen' in any function
used by the indentation engine to make it respect the value
`prog-indentation-context'.

This function (like 'widen') is useful inside a
`save-restriction' to make the indentation correctly work when
narrowing is in effect."
  (widen)
  (let ((chunk (cadr prog-indentation-context)))
    (when chunk
      (narrow-to-region (car chunk) (or (cdr chunk) (point-max))))))


(defvar-local prettify-symbols-alist nil
  "Alist of symbol prettifications.
Each element looks like (SYMBOL . CHARACTER), where the symbol
matching SYMBOL (a string, not a regexp) will be shown as
CHARACTER instead.")

(defun prettify-symbols--compose-symbol (alist)
  "Compose a sequence of characters into a symbol.
Regexp match data 0 points to the chars."
  ;; Check that the chars should really be composed into a symbol.
  (let* ((start (match-beginning 0))
	 (end (match-end 0))
	 (syntaxes-beg (if (memq (char-syntax (char-after start)) '(?w ?_))
                           '(?w ?_) '(?. ?\\)))
	 (syntaxes-end (if (memq (char-syntax (char-before end)) '(?w ?_))
		       '(?w ?_) '(?. ?\\)))
	 match)
    (if (or (memq (char-syntax (or (char-before start) ?\s)) syntaxes-beg)
	    (memq (char-syntax (or (char-after end) ?\s)) syntaxes-end)
            ;; syntax-ppss could modify the match data (bug#14595)
            (progn (setq match (match-string 0)) (nth 8 (syntax-ppss))))
	;; No composition for you.  Let's actually remove any composition
	;; we may have added earlier and which is now incorrect.
	(remove-text-properties start end '(composition))
      ;; That's a symbol alright, so add the composition.
      (compose-region start end (cdr (assoc match alist)))))
  ;; Return nil because we're not adding any face property.
  nil)

(defun prettify-symbols--make-keywords ()
  (if prettify-symbols-alist
      `((,(regexp-opt (mapcar 'car prettify-symbols-alist) t)
         (0 (prettify-symbols--compose-symbol ',prettify-symbols-alist))))
    nil))

(defvar-local prettify-symbols--keywords nil)

;;;###autoload
(define-minor-mode prettify-symbols-mode
  "Toggle Prettify Symbols mode.
With a prefix argument ARG, enable Prettify Symbols mode if ARG is
positive, and disable it otherwise.  If called from Lisp, enable
the mode if ARG is omitted or nil.

When Prettify Symbols mode and font-locking are enabled, symbols are
prettified (displayed as composed characters) according to the rules
in `prettify-symbols-alist' (which see), which are locally defined
by major modes supporting prettifying.  To add further customizations
for a given major mode, you can modify `prettify-symbols-alist' thus:

  (add-hook 'emacs-lisp-mode-hook
            (lambda ()
              (push '(\"<=\" . ?≤) prettify-symbols-alist)))

You can enable this mode locally in desired buffers, or use
`global-prettify-symbols-mode' to enable it for all modes that
support it."
  :init-value nil
  (if prettify-symbols-mode
      ;; Turn on
      (when (setq prettify-symbols--keywords (prettify-symbols--make-keywords))
        (font-lock-add-keywords nil prettify-symbols--keywords)
        (setq-local font-lock-extra-managed-props
                    (cons 'composition font-lock-extra-managed-props))
        (font-lock-flush))
    ;; Turn off
    (when prettify-symbols--keywords
      (font-lock-remove-keywords nil prettify-symbols--keywords)
      (setq prettify-symbols--keywords nil))
    (when (memq 'composition font-lock-extra-managed-props)
      (setq font-lock-extra-managed-props (delq 'composition
                                                font-lock-extra-managed-props))
      (with-silent-modifications
        (remove-text-properties (point-min) (point-max) '(composition nil))))))

(defun turn-on-prettify-symbols-mode ()
  (when (and (not prettify-symbols-mode)
             (local-variable-p 'prettify-symbols-alist))
    (prettify-symbols-mode 1)))

;;;###autoload
(define-globalized-minor-mode global-prettify-symbols-mode
  prettify-symbols-mode turn-on-prettify-symbols-mode)

;;;###autoload
(define-derived-mode prog-mode fundamental-mode "Prog"
  "Major mode for editing programming language source code."
  (setq-local require-final-newline mode-require-final-newline)
  (setq-local parse-sexp-ignore-comments t)
  ;; Any programming language is always written left to right.
  (setq bidi-paragraph-direction 'left-to-right))

(provide 'prog-mode)

;;; prog-mode.el ends here

debug log:

solving 33abb6d ...
found 33abb6d in https://yhetil.org/emacs/F9C2521BBF380A4A97379009991555E685B7FAF5@DEWDFEMB17C.global.corp.sap/
found 0d9fabd in https://git.savannah.gnu.org/cgit/emacs.git
preparing index
index prepared:
100644 0d9fabd2057829a6a87624de71dd789fc93f35f5	lisp/progmodes/prog-mode.el

applying [1/1] https://yhetil.org/emacs/F9C2521BBF380A4A97379009991555E685B7FAF5@DEWDFEMB17C.global.corp.sap/
diff --git a/lisp/progmodes/prog-mode.el b/lisp/progmodes/prog-mode.el
index 0d9fabd..33abb6d 100644

Checking patch lisp/progmodes/prog-mode.el...
Applied patch lisp/progmodes/prog-mode.el cleanly.

index at:
100644 33abb6d92cb0b084a536436307cfa528af5bde90	lisp/progmodes/prog-mode.el

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.