diff options
Diffstat (limited to 'lisp')
-rw-r--r-- | lisp/ChangeLog | 68 | ||||
-rw-r--r-- | lisp/button.el | 20 | ||||
-rw-r--r-- | lisp/erc/ChangeLog | 5 | ||||
-rw-r--r-- | lisp/erc/erc-backend.el | 7 | ||||
-rw-r--r-- | lisp/filenotify.el | 383 | ||||
-rw-r--r-- | lisp/files.el | 8 | ||||
-rw-r--r-- | lisp/gnus/gnus-setup.el | 191 | ||||
-rw-r--r-- | lisp/net/net-utils.el | 20 | ||||
-rw-r--r-- | lisp/net/tramp.el | 3 | ||||
-rw-r--r-- | lisp/progmodes/cap-words.el | 98 | ||||
-rw-r--r-- | lisp/progmodes/python.el | 702 | ||||
-rw-r--r-- | lisp/progmodes/sh-script.el | 7 | ||||
-rw-r--r-- | lisp/subr.el | 33 | ||||
-rw-r--r-- | lisp/textmodes/artist.el | 95 | ||||
-rw-r--r-- | lisp/w32-common-fns.el | 134 |
15 files changed, 1181 insertions, 593 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog index 0e22c76abe0..eb6ef6b19d2 100644 --- a/lisp/ChangeLog +++ b/lisp/ChangeLog @@ -1,3 +1,68 @@ +2015-01-26 Fabián Ezequiel Gallina <fgallina@gnu.org> + + python.el: New non-global state dependent indentation engine. + (Bug#18319, Bug#19595) + + * progmodes/python.el (python-syntax-comment-or-string-p): Accept + PPSS as argument. + (python-syntax-closing-paren-p): New function. + (python-indent-current-level) + (python-indent-levels): Mark obsolete. + (python-indent-context): Return more context cases. + (python-indent--calculate-indentation) + (python-indent--calculate-levels): New functions. + (python-indent-calculate-levels): Use them. + (python-indent-calculate-indentation, python-indent-line): + (python-indent-line-function): Rewritten to use new API. + (python-indent-dedent-line): Simplify logic. + (python-indent-dedent-line-backspace): Use `unless`. + (python-indent-toggle-levels): Delete function. + +2015-01-21 Daniel Koning <dk@danielkoning.com> (tiny change) + + * subr.el (posnp): Correct docstring of `posnp'. + (posn-col-row): Make it work with all mouse position objects. + * textmodes/artist.el (artist-mouse-draw-continously): Cancel + timers if an error occurs during continuous drawing. (Bug#6130) + +2015-01-20 Eli Zaretskii <eliz@gnu.org> + + * button.el (button-activate, push-button): Doc fix. (Bug#19628) + +2015-01-13 Michael Albinus <michael.albinus@gmx.de> + + * filenotify.el (file-notify-descriptors, file-notify-handle-event): + Adapt docstring. + (file-notify--descriptor): New defun. + (file-notify-callback, file-notify-add-watch, file-notify-rm-watch): + Adapt docstring. Handle multiple values for + `file-notify-descriptors' entries. (Bug#18880) + + * net/tramp.el (tramp-handle-file-notify-rm-watch): Do not check + `file-notify-descriptors', the implementation has been changed. + +2015-01-09 Eli Zaretskii <eliz@gnu.org> + + * net/net-utils.el (net-utils-run-program, net-utils-run-simple): + On MS-Windows, bind coding-system-for-read to the console output + codepage. (Bug#19458) + +2015-01-04 Dmitry Gutov <dgutov@yandex.ru> + + Unbreak `mouse-action' property in text buttons. + + * button.el (push-button): Fix regression from 2012-12-06. + +2015-01-06 Glenn Morris <rgm@gnu.org> + + * progmodes/sh-script.el (sh-mode): Doc fix. + (sh-basic-indent-line): Handle electric newline. (Bug#18756) + +2015-01-04 Paul Eggert <eggert@cs.ucla.edu> + + Fix dired quoting bug with "Hit`N`Hide". Fixes Bug#19498. + * files.el (shell-quote-wildcard-pattern): Also quote "`". + 2015-01-28 Stefan Monnier <monnier@iro.umontreal.ca> Tighten up the tagcode used for eieio and cl-struct objects. @@ -1777,8 +1842,7 @@ 2014-12-14 Steve Purcell <steve@sanityinc.com> (tiny change) * emacs-lisp/package.el (package-menu-mode): Use an extra column - for the "Version" column, to accomodate date-and-time-based - versions. + for the "Version" column, to accomodate date-and-time-based versions. 2014-12-14 Cameron Desautels <camdez@gmail.com> diff --git a/lisp/button.el b/lisp/button.el index 189a1c23a4d..e7602dd7050 100644 --- a/lisp/button.el +++ b/lisp/button.el @@ -224,10 +224,10 @@ changes to a supertype are not reflected in its subtypes)." prop val)))) (defun button-activate (button &optional use-mouse-action) - "Call BUTTON's action property. -If USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action -instead of its normal action; if the button has no mouse-action, -the normal action is used instead. + "Call BUTTON's `action' property. +If USE-MOUSE-ACTION is non-nil, invoke the button's `mouse-action' +property instead of `action'; if the button has no `mouse-action', +the value of `action' is used instead. The action can either be a marker or a function. If it's a marker then goto it. Otherwise it it is a function then it is @@ -429,11 +429,13 @@ instead of starting at the next button." (defun push-button (&optional pos use-mouse-action) "Perform the action specified by a button at location POS. POS may be either a buffer position or a mouse-event. If -USE-MOUSE-ACTION is non-nil, invoke the button's mouse-action -instead of its normal action; if the button has no mouse-action, -the normal action is used instead. The action may be either a -function to call or a marker to display and is invoked using -`button-activate' (which see). +USE-MOUSE-ACTION is non-nil, invoke the button's `mouse-action' +property instead of its `action' property; if the button has no +`mouse-action', the value of `action' is used instead. + +The action in both cases may be either a function to call or a +marker to display and is invoked using `button-activate' (which +see). POS defaults to point, except when `push-button' is invoked interactively as the result of a mouse-event, in which case, the diff --git a/lisp/erc/ChangeLog b/lisp/erc/ChangeLog index 28ac7d38b96..ba5d57e4d2e 100644 --- a/lisp/erc/ChangeLog +++ b/lisp/erc/ChangeLog @@ -1,3 +1,8 @@ +2015-01-14 Dima Kogan <dima@secretsauce.net> + + * erc-backend.el (define-erc-response-handler): Give hook-name + default value of nil and add-to-list (bug#19363) + 2015-01-22 Paul Eggert <eggert@cs.ucla.edu> Don't downcase system diagnostics' first letters diff --git a/lisp/erc/erc-backend.el b/lisp/erc/erc-backend.el index b8c67860e20..8ce199fbcbb 100644 --- a/lisp/erc/erc-backend.el +++ b/lisp/erc/erc-backend.el @@ -1162,8 +1162,11 @@ add things to `%s' instead." (cl-loop for alias in aliases collect (intern (format "erc-server-%s-functions" alias))))) `(prog2 - ;; Normal hook variable. - (defvar ,hook-name ',fn-name ,(format hook-doc name)) + ;; Normal hook variable. The variable may already have a + ;; value at this point, so I default to nil, and (add-hook) + ;; unconditionally + (defvar ,hook-name nil ,(format hook-doc name)) + (add-to-list ',hook-name ',fn-name) ;; Handler function (defun ,fn-name (proc parsed) ,fn-doc diff --git a/lisp/filenotify.el b/lisp/filenotify.el index 35181b63f3a..c94f631dde8 100644 --- a/lisp/filenotify.el +++ b/lisp/filenotify.el @@ -41,13 +41,21 @@ could use another implementation.") "Hash table for registered file notification descriptors. A key in this hash table is the descriptor as returned from `gfilenotify', `inotify', `w32notify' or a file name handler. -The value in the hash table is the cons cell (DIR FILE CALLBACK).") +The value in the hash table is a list + + \(DIR (FILE . CALLBACK) (FILE . CALLBACK) ...) + +Several values for a given DIR happen only for `inotify', when +different files from the same directory are watched.") ;; This function is used by `gfilenotify', `inotify' and `w32notify' events. ;;;###autoload (defun file-notify-handle-event (event) "Handle file system monitoring event. -If EVENT is a filewatch event, call its callback. +If EVENT is a filewatch event, call its callback. It has the format + + \(file-notify (DESCRIPTOR ACTIONS FILE COOKIE) CALLBACK) + Otherwise, signal a `file-notify-error'." (interactive "e") (if (and (eq (car event) 'file-notify) @@ -81,12 +89,23 @@ This is available in case a file has been moved." This is available in case a file has been moved." (nth 3 event)) +;; `inotify' returns the same descriptor when the file (directory) +;; uses the same inode. We want to distinguish, and apply a virtual +;; descriptor which make the difference. +(defun file-notify--descriptor (descriptor file) + "Return the descriptor to be used in `file-notify-*-watch'. +For `gfilenotify' and `w32notify' it is the same descriptor as +used in the low-level file notification package." + (if (and (natnump descriptor) (eq file-notify--library 'inotify)) + (cons descriptor file) + descriptor)) + ;; The callback function used to map between specific flags of the ;; respective file notifications, and the ones we return. (defun file-notify-callback (event) "Handle an EVENT returned from file notification. -EVENT is the same one as in `file-notify-handle-event' except the -car of that event, which is the symbol `file-notify'." +EVENT is the cdr of the event in `file-notify-handle-event' +\(DESCRIPTOR ACTIONS FILE COOKIE)." (let* ((desc (car event)) (registered (gethash desc file-notify-descriptors)) (pending-event (assoc desc file-notify--pending-events)) @@ -97,99 +116,113 @@ car of that event, which is the symbol `file-notify'." ;; Make actions a list. (unless (consp actions) (setq actions (cons actions nil))) - ;; Check, that event is meant for us. - (unless (setq callback (nth 2 registered)) - (setq actions nil)) - - ;; Loop over actions. In fact, more than one action happens only - ;; for `inotify'. - (dolist (action actions) - - ;; Send pending event, if it doesn't match. - (when (and pending-event - ;; The cookie doesn't match. - (not (eq (file-notify--event-cookie pending-event) - (file-notify--event-cookie event))) - (or - ;; inotify. - (and (eq (nth 1 pending-event) 'moved-from) - (not (eq action 'moved-to))) - ;; w32notify. - (and (eq (nth 1 pending-event) 'renamed-from) - (not (eq action 'renamed-to))))) - (funcall callback - (list desc 'deleted - (file-notify--event-file-name pending-event))) - (setq file-notify--pending-events - (delete pending-event file-notify--pending-events))) - - ;; Map action. We ignore all events which cannot be mapped. - (setq action - (cond - ;; gfilenotify. - ((memq action '(attribute-changed changed created deleted)) action) - ((eq action 'moved) - (setq file1 (file-notify--event-file1-name event)) - 'renamed) - - ;; inotify. - ((eq action 'attrib) 'attribute-changed) - ((eq action 'create) 'created) - ((eq action 'modify) 'changed) - ((memq action '(delete 'delete-self move-self)) 'deleted) - ;; Make the event pending. - ((eq action 'moved-from) - (add-to-list 'file-notify--pending-events - (list desc action file - (file-notify--event-cookie event))) - nil) - ;; Look for pending event. - ((eq action 'moved-to) - (if (null pending-event) - 'created - (setq file1 file - file (file-notify--event-file-name pending-event) - file-notify--pending-events - (delete pending-event file-notify--pending-events)) - 'renamed)) - - ;; w32notify. - ((eq action 'added) 'created) - ((eq action 'modified) 'changed) - ((eq action 'removed) 'deleted) - ;; Make the event pending. - ((eq 'renamed-from action) - (add-to-list 'file-notify--pending-events - (list desc action file - (file-notify--event-cookie event))) - nil) - ;; Look for pending event. - ((eq 'renamed-to action) - (if (null pending-event) - 'created - (setq file1 file - file (file-notify--event-file-name pending-event) - file-notify--pending-events - (delete pending-event file-notify--pending-events)) - 'renamed)))) - - ;; Apply callback. - (when (and action - (or - ;; If there is no relative file name for that watch, - ;; we watch the whole directory. - (null (nth 1 registered)) - ;; File matches. - (string-equal - (nth 1 registered) (file-name-nondirectory file)) - ;; File1 matches. - (and (stringp file1) - (string-equal - (nth 1 registered) (file-name-nondirectory file1))))) - (if file1 - (funcall callback (list desc action file file1)) - (funcall callback (list desc action file))))))) - + ;; Loop over registered entries. In fact, more than one entry + ;; happens only for `inotify'. + (dolist (entry (cdr registered)) + + ;; Check, that event is meant for us. + (unless (setq callback (cdr entry)) + (setq actions nil)) + + ;; Loop over actions. In fact, more than one action happens only + ;; for `inotify'. + (dolist (action actions) + + ;; Send pending event, if it doesn't match. + (when (and pending-event + ;; The cookie doesn't match. + (not (eq (file-notify--event-cookie pending-event) + (file-notify--event-cookie event))) + (or + ;; inotify. + (and (eq (nth 1 pending-event) 'moved-from) + (not (eq action 'moved-to))) + ;; w32notify. + (and (eq (nth 1 pending-event) 'renamed-from) + (not (eq action 'renamed-to))))) + (funcall callback + (list desc 'deleted + (file-notify--event-file-name pending-event))) + (setq file-notify--pending-events + (delete pending-event file-notify--pending-events))) + + ;; Map action. We ignore all events which cannot be mapped. + (setq action + (cond + ;; gfilenotify. + ((memq action '(attribute-changed changed created deleted)) + action) + ((eq action 'moved) + (setq file1 (file-notify--event-file1-name event)) + 'renamed) + + ;; inotify. + ((eq action 'attrib) 'attribute-changed) + ((eq action 'create) 'created) + ((eq action 'modify) 'changed) + ((memq action '(delete 'delete-self move-self)) 'deleted) + ;; Make the event pending. + ((eq action 'moved-from) + (add-to-list 'file-notify--pending-events + (list desc action file + (file-notify--event-cookie event))) + nil) + ;; Look for pending event. + ((eq action 'moved-to) + (if (null pending-event) + 'created + (setq file1 file + file (file-notify--event-file-name pending-event) + file-notify--pending-events + (delete pending-event file-notify--pending-events)) + 'renamed)) + + ;; w32notify. + ((eq action 'added) 'created) + ((eq action 'modified) 'changed) + ((eq action 'removed) 'deleted) + ;; Make the event pending. + ((eq action 'renamed-from) + (add-to-list 'file-notify--pending-events + (list desc action file + (file-notify--event-cookie event))) + nil) + ;; Look for pending event. + ((eq action 'renamed-to) + (if (null pending-event) + 'created + (setq file1 file + file (file-notify--event-file-name pending-event) + file-notify--pending-events + (delete pending-event file-notify--pending-events)) + 'renamed)))) + + ;; Apply callback. + (when (and action + (or + ;; If there is no relative file name for that watch, + ;; we watch the whole directory. + (null (nth 0 entry)) + ;; File matches. + (string-equal + (nth 0 entry) (file-name-nondirectory file)) + ;; File1 matches. + (and (stringp file1) + (string-equal + (nth 0 entry) (file-name-nondirectory file1))))) + (if file1 + (funcall + callback + `(,(file-notify--descriptor desc (nth 0 entry)) + ,action ,file ,file1)) + (funcall + callback + `(,(file-notify--descriptor desc (nth 0 entry)) + ,action ,file)))))))) + +;; `gfilenotify' and `w32notify' return a unique descriptor for every +;; `file-notify-add-watch', while `inotify' returns a unique +;; descriptor per inode only. (defun file-notify-add-watch (file flags callback) "Add a watch for filesystem events pertaining to FILE. This arranges for filesystem events pertaining to FILE to be reported @@ -206,7 +239,7 @@ include the following symbols: `attribute-change' -- watch for file attributes changes, like permissions or modification time -If FILE is a directory, 'change' watches for file creation or +If FILE is a directory, `change' watches for file creation or deletion in that directory. This does not work recursively. When any event happens, Emacs will call the CALLBACK function passing @@ -240,82 +273,96 @@ FILE is the name of the file whose event is being reported." (if (file-directory-p file) file (file-name-directory file)))) - desc func l-flags) - - ;; Check, whether this has been registered already. -; (maphash -; (lambda (key value) -; (when (equal (cons file callback) value) (setq desc key))) -; file-notify-descriptors) - - (unless desc - (if handler - ;; A file name handler could exist even if there is no local - ;; file notification support. - (setq desc (funcall - handler 'file-notify-add-watch dir flags callback)) - - ;; Check, whether Emacs has been compiled with file - ;; notification support. - (unless file-notify--library - (signal 'file-notify-error - '("No file notification package available"))) - - ;; Determine low-level function to be called. - (setq func - (cond - ((eq file-notify--library 'gfilenotify) 'gfile-add-watch) - ((eq file-notify--library 'inotify) 'inotify-add-watch) - ((eq file-notify--library 'w32notify) 'w32notify-add-watch))) - - ;; Determine respective flags. - (if (eq file-notify--library 'gfilenotify) - (setq l-flags '(watch-mounts send-moved)) - (when (memq 'change flags) - (setq - l-flags - (cond - ((eq file-notify--library 'inotify) '(create modify move delete)) - ((eq file-notify--library 'w32notify) - '(file-name directory-name size last-write-time))))) - (when (memq 'attribute-change flags) - (add-to-list - 'l-flags - (cond - ((eq file-notify--library 'inotify) 'attrib) - ((eq file-notify--library 'w32notify) 'attributes))))) - - ;; Call low-level function. - (setq desc (funcall func dir l-flags 'file-notify-callback)))) + desc func l-flags registered) + + (if handler + ;; A file name handler could exist even if there is no local + ;; file notification support. + (setq desc (funcall + handler 'file-notify-add-watch dir flags callback)) + + ;; Check, whether Emacs has been compiled with file + ;; notification support. + (unless file-notify--library + (signal 'file-notify-error + '("No file notification package available"))) + + ;; Determine low-level function to be called. + (setq func + (cond + ((eq file-notify--library 'gfilenotify) 'gfile-add-watch) + ((eq file-notify--library 'inotify) 'inotify-add-watch) + ((eq file-notify--library 'w32notify) 'w32notify-add-watch))) + + ;; Determine respective flags. + (if (eq file-notify--library 'gfilenotify) + (setq l-flags '(watch-mounts send-moved)) + (when (memq 'change flags) + (setq + l-flags + (cond + ((eq file-notify--library 'inotify) '(create modify move delete)) + ((eq file-notify--library 'w32notify) + '(file-name directory-name size last-write-time))))) + (when (memq 'attribute-change flags) + (add-to-list + 'l-flags + (cond + ((eq file-notify--library 'inotify) 'attrib) + ((eq file-notify--library 'w32notify) 'attributes))))) + + ;; Call low-level function. + (setq desc (funcall func dir l-flags 'file-notify-callback))) + + ;; Modify `file-notify-descriptors'. + (setq registered (gethash desc file-notify-descriptors)) + (puthash + desc + `(,dir + (,(unless (file-directory-p file) (file-name-nondirectory file)) + . ,callback) + . ,(cdr registered)) + file-notify-descriptors) ;; Return descriptor. - (puthash desc - (list (directory-file-name - (if (file-directory-p dir) dir (file-name-directory dir))) - (unless (file-directory-p file) - (file-name-nondirectory file)) - callback) - file-notify-descriptors) - desc)) + (file-notify--descriptor + desc (unless (file-directory-p file) (file-name-nondirectory file))))) (defun file-notify-rm-watch (descriptor) "Remove an existing watch specified by its DESCRIPTOR. DESCRIPTOR should be an object returned by `file-notify-add-watch'." - (let ((file (car (gethash descriptor file-notify-descriptors))) - handler) - - (when (stringp file) - (setq handler (find-file-name-handler file 'file-notify-rm-watch)) - (if handler - (funcall handler 'file-notify-rm-watch descriptor) - (funcall - (cond - ((eq file-notify--library 'gfilenotify) 'gfile-rm-watch) - ((eq file-notify--library 'inotify) 'inotify-rm-watch) - ((eq file-notify--library 'w32notify) 'w32notify-rm-watch)) - descriptor))) - - (remhash descriptor file-notify-descriptors))) + (let* ((desc (if (consp descriptor) (car descriptor) descriptor)) + (file (if (consp descriptor) (cdr descriptor))) + (dir (car (gethash desc file-notify-descriptors))) + handler registered) + + (when (stringp dir) + (setq handler (find-file-name-handler dir 'file-notify-rm-watch)) + + ;; Modify `file-notify-descriptors'. + (if (not file) + (remhash desc file-notify-descriptors) + + (setq registered (gethash desc file-notify-descriptors)) + (setcdr registered + (delete (assoc file (cdr registered)) (cdr registered))) + (if (null (cdr registered)) + (remhash desc file-notify-descriptors) + (puthash desc registered file-notify-descriptors))) + + ;; Call low-level function. + (when (null (cdr registered)) + (if handler + ;; A file name handler could exist even if there is no local + ;; file notification support. + (funcall handler 'file-notify-rm-watch desc) + + (funcall + (cond + ((eq file-notify--library 'gfilenotify) 'gfile-rm-watch) + ((eq file-notify--library 'inotify) 'inotify-rm-watch) + ((eq file-notify--library 'w32notify) 'w32notify-rm-watch)) + desc)))))) ;; The end: (provide 'filenotify) diff --git a/lisp/files.el b/lisp/files.el index ed1943dfc28..40a42897419 100644 --- a/lisp/files.el +++ b/lisp/files.el @@ -6094,7 +6094,7 @@ and `list-directory-verbose-switches'." PATTERN is assumed to represent a file-name wildcard suitable for the underlying filesystem. For Unix and GNU/Linux, each character from the -set [ \\t\\n;<>&|()'\"#$] is quoted with a backslash; for DOS/Windows, all +set [ \\t\\n;<>&|()`'\"#$] is quoted with a backslash; for DOS/Windows, all the parts of the pattern which don't include wildcard characters are quoted with double quotes. @@ -6108,12 +6108,12 @@ need to be passed verbatim to shell commands." ;; argument has quotes, we can safely assume it is already ;; quoted by the caller. (if (or (string-match "[\"]" pattern) - ;; We quote [&()#$'] in case their shell is a port of a + ;; We quote [&()#$`'] in case their shell is a port of a ;; Unixy shell. We quote [,=+] because stock DOS and ;; Windows shells require that in some cases, such as ;; passing arguments to batch files that use positional ;; arguments like %1. - (not (string-match "[ \t;&()#$',=+]" pattern))) + (not (string-match "[ \t;&()#$`',=+]" pattern))) pattern (let ((result "\"") (beg 0) @@ -6128,7 +6128,7 @@ need to be passed verbatim to shell commands." (concat result (substring pattern beg) "\"")))) (t (let ((beg 0)) - (while (string-match "[ \t\n;<>&|()'\"#$]" pattern beg) + (while (string-match "[ \t\n;<>&|()`'\"#$]" pattern beg) (setq pattern (concat (substring pattern 0 (match-beginning 0)) "\\" diff --git a/lisp/gnus/gnus-setup.el b/lisp/gnus/gnus-setup.el new file mode 100644 index 00000000000..86b3bffcd4a --- /dev/null +++ b/lisp/gnus/gnus-setup.el @@ -0,0 +1,191 @@ +;;; gnus-setup.el --- Initialization & Setup for Gnus 5 + +;; Copyright (C) 1995-1996, 2000-2015 Free Software Foundation, Inc. + +;; Author: Steven L. Baur <steve@miranova.com> +;; Keywords: news + +;; 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: +;; My head is starting to spin with all the different mail/news packages. +;; Stop The Madness! + +;; Given that Emacs Lisp byte codes may be diverging, it is probably best +;; not to byte compile this, and just arrange to have the .el loaded out +;; of .emacs. + +;;; Code: + +(eval-when-compile (require 'cl)) + +(defvar gnus-use-installed-gnus t + "*If non-nil use installed version of Gnus.") + +(defvar gnus-use-installed-mailcrypt (featurep 'xemacs) + "*If non-nil use installed version of mailcrypt.") + +(defvar gnus-emacs-lisp-directory (if (featurep 'xemacs) + "/usr/local/lib/xemacs/" + "/usr/local/share/emacs/") + "Directory where Emacs site lisp is located.") + +(defvar gnus-gnus-lisp-directory (concat gnus-emacs-lisp-directory + "gnus/lisp/") + "Directory where Gnus Emacs lisp is found.") + +(defvar gnus-mailcrypt-lisp-directory (concat gnus-emacs-lisp-directory + "site-lisp/mailcrypt/") + "Directory where Mailcrypt Emacs Lisp is found.") + +(defvar gnus-bbdb-lisp-directory (concat gnus-emacs-lisp-directory + "site-lisp/bbdb/") + "Directory where Big Brother Database is found.") + +(defvar gnus-use-mhe nil + "Set this if you want to use MH-E for mail reading.") +(defvar gnus-use-rmail nil + "Set this if you want to use RMAIL for mail reading.") +(defvar gnus-use-sendmail nil + "Set this if you want to use SENDMAIL for mail reading.") +(defvar gnus-use-vm nil + "Set this if you want to use the VM package for mail reading.") +(defvar gnus-use-sc nil + "Set this if you want to use Supercite.") +(defvar gnus-use-mailcrypt t + "Set this if you want to use Mailcrypt for dealing with PGP messages.") +(defvar gnus-use-bbdb nil + "Set this if you want to use the Big Brother DataBase.") + +(when (and (not gnus-use-installed-gnus) + (null (member gnus-gnus-lisp-directory load-path))) + (push gnus-gnus-lisp-directory load-path)) + +;;; We can't do this until we know where Gnus is. +(require 'message) + +;;; Mailcrypt by +;;; Jin Choi <jin@atype.com> +;;; Patrick LoPresti <patl@lcs.mit.edu> + +(when gnus-use-mailcrypt + (when (and (not gnus-use-installed-mailcrypt) + (null (member gnus-mailcrypt-lisp-directory load-path))) + (setq load-path (cons gnus-mailcrypt-lisp-directory load-path))) + (autoload 'mc-install-write-mode "mailcrypt" nil t) + (autoload 'mc-install-read-mode "mailcrypt" nil t) +;;; (add-hook 'message-mode-hook 'mc-install-write-mode) +;;; (add-hook 'gnus-summary-mode-hook 'mc-install-read-mode) + (when gnus-use-mhe + (add-hook 'mh-folder-mode-hook 'mc-install-read-mode) + (add-hook 'mh-letter-mode-hook 'mc-install-write-mode))) + +;;; BBDB by +;;; Jamie Zawinski <jwz@lucid.com> + +(when gnus-use-bbdb + ;; bbdb will never be installed with emacs. + (when (null (member gnus-bbdb-lisp-directory load-path)) + (setq load-path (cons gnus-bbdb-lisp-directory load-path))) + (autoload 'bbdb "bbdb-com" + "Insidious Big Brother Database" t) + (autoload 'bbdb-name "bbdb-com" + "Insidious Big Brother Database" t) + (autoload 'bbdb-company "bbdb-com" + "Insidious Big Brother Database" t) + (autoload 'bbdb-net "bbdb-com" + "Insidious Big Brother Database" t) + (autoload 'bbdb-notes "bbdb-com" + "Insidious Big Brother Database" t) + + (when gnus-use-vm + (autoload 'bbdb-insinuate-vm "bbdb-vm" + "Hook BBDB into VM" t)) + + (when gnus-use-rmail + (autoload 'bbdb-insinuate-rmail "bbdb-rmail" + "Hook BBDB into RMAIL" t) + (add-hook 'rmail-mode-hook 'bbdb-insinuate-rmail)) + + (when gnus-use-mhe + (autoload 'bbdb-insinuate-mh "bbdb-mh" + "Hook BBDB into MH-E" t) + (add-hook 'mh-folder-mode-hook 'bbdb-insinuate-mh)) + + (autoload 'bbdb-insinuate-gnus "bbdb-gnus" + "Hook BBDB into Gnus" t) + (add-hook 'gnus-startup-hook 'bbdb-insinuate-gnus) + + (when gnus-use-sendmail + (autoload 'bbdb-insinuate-sendmail "bbdb" + "Insidious Big Brother Database" t) + (add-hook 'mail-setup-hook 'bbdb-insinuate-sendmail) + (add-hook 'message-setup-hook 'bbdb-insinuate-sendmail))) + +(when gnus-use-sc + (add-hook 'mail-citation-hook 'sc-cite-original) + (setq message-cite-function 'sc-cite-original)) + +;;;### (autoloads (gnus gnus-slave gnus-no-server) "gnus" "lisp/gnus.el" (12473 2137)) +;;; Generated autoloads from lisp/gnus.el + +;; Don't redo this if autoloads already exist +(unless (fboundp 'gnus) + (autoload 'gnus-slave-no-server "gnus" "\ +Read network news as a slave without connecting to local server." t nil) + + (autoload 'gnus-no-server "gnus" "\ +Read network news. +If ARG is a positive number, Gnus will use that as the +startup level. If ARG is nil, Gnus will be started at level 2. +If ARG is non-nil and not a positive number, Gnus will +prompt the user for the name of an NNTP server to use. +As opposed to `gnus', this command will not connect to the local server." t nil) + + (autoload 'gnus-slave "gnus" "\ +Read news as a slave." t nil) + + (autoload 'gnus "gnus" "\ +Read network news. +If ARG is non-nil and a positive number, Gnus will use that as the +startup level. If ARG is non-nil and not a positive number, Gnus will +prompt the user for the name of an NNTP server to use." t nil) + +;;;*** + +;;; These have moved out of gnus.el into other files. +;;; FIX FIX FIX: should other things be in gnus-setup? or these not in it? + (autoload 'gnus-update-format "gnus-spec" "\ +Update the format specification near point." t nil) + + (autoload 'gnus-fetch-group "gnus-group" "\ +Start Gnus if necessary and enter GROUP. +Returns whether the fetching was successful or not." t nil) + + (defalias 'gnus-batch-kill 'gnus-batch-score) + + (autoload 'gnus-batch-score "gnus-kill" "\ +Run batched scoring. +Usage: emacs -batch -l gnus -f gnus-batch-score <newsgroups> ... +Newsgroups is a list of strings in Bnews format. If you want to score +the comp hierarchy, you'd say \"comp.all\". If you would not like to +score the alt hierarchy, you'd say \"!alt.all\"." t nil)) + +(provide 'gnus-setup) + +(run-hooks 'gnus-setup-load-hook) + +;;; gnus-setup.el ends here diff --git a/lisp/net/net-utils.el b/lisp/net/net-utils.el index 28aa43117da..ebcbc714ffb 100644 --- a/lisp/net/net-utils.el +++ b/lisp/net/net-utils.el @@ -328,7 +328,15 @@ This variable is only used if the variable (defun net-utils-run-program (name header program args) "Run a network information program." - (let ((buf (get-buffer-create (concat "*" name "*")))) + (let ((buf (get-buffer-create (concat "*" name "*"))) + (coding-system-for-read + ;; MS-Windows versions of network utilities output text + ;; encoded in the console (a.k.a. "OEM") codepage, which is + ;; different from the default system (a.k.a. "ANSI") + ;; codepage. + (if (eq system-type 'windows-nt) + (intern (format "cp%d" (w32-get-console-output-codepage))) + coding-system-for-read))) (set-buffer buf) (erase-buffer) (insert header "\n") @@ -352,7 +360,15 @@ This variable is only used if the variable (when proc (set-process-filter proc nil) (delete-process proc))) - (let ((inhibit-read-only t)) + (let ((inhibit-read-only t) + (coding-system-for-read + ;; MS-Windows versions of network utilities output text + ;; encoded in the console (a.k.a. "OEM") codepage, which is + ;; different from the default system (a.k.a. "ANSI") + ;; codepage. + (if (eq system-type 'windows-nt) + (intern (format "cp%d" (w32-get-console-output-codepage))) + coding-system-for-read))) (erase-buffer)) (net-utils-mode) (setq-local net-utils--revert-cmd diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index d44c8ea2f6d..ba0d13eab8b 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -64,7 +64,6 @@ (defvar bkup-backup-directory-info) (defvar directory-sep-char) (defvar eshell-path-env) -(defvar file-notify-descriptors) (defvar ls-lisp-use-insert-directory-program) (defvar outline-regexp) @@ -3415,7 +3414,7 @@ of." (defun tramp-handle-file-notify-rm-watch (proc) "Like `file-notify-rm-watch' for Tramp files." ;; The descriptor must be a process object. - (unless (and (processp proc) (gethash proc file-notify-descriptors)) + (unless (processp proc) (tramp-error proc 'file-notify-error "Not a valid descriptor %S" proc)) (tramp-message proc 6 "Kill %S" proc) (kill-process proc)) diff --git a/lisp/progmodes/cap-words.el b/lisp/progmodes/cap-words.el new file mode 100644 index 00000000000..94e865db62b --- /dev/null +++ b/lisp/progmodes/cap-words.el @@ -0,0 +1,98 @@ +;;; cap-words.el --- minor mode for motion in CapitalizedWordIdentifiers + +;; Copyright (C) 2002-2015 Free Software Foundation, Inc. + +;; Author: Dave Love <fx@gnu.org> +;; Keywords: languages + +;; 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: + +;; Provides Capitalized Words minor mode for word movement in +;; identifiers CapitalizedLikeThis. + +;; Note that the same effect could be obtained by frobbing the +;; category of upper case characters to produce word boundaries, but +;; the necessary processing isn't done for ASCII characters. + +;; Fixme: This doesn't work properly for mouse double clicks. + +;;; Code: + +(defun capitalized-find-word-boundary (pos limit) + "Function for use in `find-word-boundary-function-table'. +Looks for word boundaries before capitals." + (save-excursion + (goto-char pos) + (let (case-fold-search) + (if (<= pos limit) + ;; Fixme: Are these regexps the best? + (or (and (re-search-forward "\\=.\\w*[[:upper:]]" + limit t) + (progn (backward-char) + t)) + (re-search-forward "\\>" limit t)) + (or (re-search-backward "[[:upper:]]\\w*\\=" limit t) + (re-search-backward "\\<" limit t)))) + (point))) + + +(defconst capitalized-find-word-boundary-function-table + (let ((tab (make-char-table nil))) + (set-char-table-range tab t #'capitalized-find-word-boundary) + tab) + "Assigned to `find-word-boundary-function-table' in Capitalized Words mode.") + +;;;###autoload +(define-minor-mode capitalized-words-mode + "Toggle Capitalized Words mode. +With a prefix argument ARG, enable Capitalized Words mode if ARG +is positive, and disable it otherwise. If called from Lisp, +enable the mode if ARG is omitted or nil. + +Capitalized Words mode is a buffer-local minor mode. When +enabled, a word boundary occurs immediately before an uppercase +letter in a symbol. This is in addition to all the normal +boundaries given by the syntax and category tables. There is no +restriction to ASCII. + +E.g. the beginning of words in the following identifier are as marked: + + capitalizedWorDD + ^ ^ ^^ + +Note that these word boundaries only apply for word motion and +marking commands such as \\[forward-word]. This mode does not affect word +boundaries found by regexp matching (`\\>', `\\w' &c). + +This style of identifiers is common in environments like Java ones, +where underscores aren't trendy enough. Capitalization rules are +sometimes part of the language, e.g. Haskell, which may thus encourage +such a style. It is appropriate to add `capitalized-words-mode' to +the mode hook for programming language modes in which you encounter +variables like this, e.g. `java-mode-hook'. It's unlikely to cause +trouble if such identifiers aren't used. + +See also `glasses-mode' and `studlify-word'. +Obsoletes `c-forward-into-nomenclature'." + nil " Caps" nil :group 'programming + (set (make-local-variable 'find-word-boundary-function-table) + capitalized-find-word-boundary-function-table)) + +(provide 'cap-words) + +;;; cap-words.el ends here diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 13ff439bef2..d340550a017 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el @@ -463,9 +463,14 @@ The type returned can be `comment', `string' or `paren'." ((nth 8 ppss) (if (nth 4 ppss) 'comment 'string)) ((nth 1 ppss) 'paren)))) -(defsubst python-syntax-comment-or-string-p () - "Return non-nil if point is inside 'comment or 'string." - (nth 8 (syntax-ppss))) +(defsubst python-syntax-comment-or-string-p (&optional ppss) + "Return non-nil if PPSS is inside 'comment or 'string." + (nth 8 (or ppss (syntax-ppss)))) + +(defsubst python-syntax-closing-paren-p () + "Return non-nil if char after point is a closing paren." + (= (syntax-class (syntax-after (point))) + (syntax-class (string-to-syntax ")")))) (define-obsolete-function-alias 'python-info-ppss-context #'python-syntax-context "24.3") @@ -704,11 +709,28 @@ It makes underscores and dots word constituent chars.") 'python-guess-indent 'python-indent-guess-indent-offset "24.3") (defvar python-indent-current-level 0 - "Current indentation level `python-indent-line-function' is using.") + "Deprecated var available for compatibility.") (defvar python-indent-levels '(0) - "Levels of indentation available for `python-indent-line-function'. -Can also be `noindent' if automatic indentation can't be used.") + "Deprecated var available for compatibility.") + +(make-obsolete-variable + 'python-indent-current-level + "The indentation API changed to avoid global state. +The function `python-indent-calculate-levels' does not use it +anymore. If you were defadvising it and or depended on this +variable for indentation customizations, refactor your code to +work on `python-indent-calculate-indentation' instead." + "24.5") + +(make-obsolete-variable + 'python-indent-levels + "The indentation API changed to avoid global state. +The function `python-indent-calculate-levels' does not use it +anymore. If you were defadvising it and or depended on this +variable for indentation customizations, refactor your code to +work on `python-indent-calculate-indentation' instead." + "24.5") (defun python-indent-guess-indent-offset () "Guess and set `python-indent-offset' for the current buffer." @@ -748,362 +770,358 @@ Can also be `noindent' if automatic indentation can't be used.") python-indent-offset))))))) (defun python-indent-context () - "Get information on indentation context. -Context information is returned with a cons with the form: - (STATUS . START) - -Where status can be any of the following symbols: - - * after-comment: When current line might continue a comment block - * inside-paren: If point in between (), {} or [] - * inside-string: If point is inside a string - * after-backslash: Previous line ends in a backslash - * after-beginning-of-block: Point is after beginning of block - * after-line: Point is after normal line - * dedenter-statement: Point is on a dedenter statement. - * no-indent: Point is at beginning of buffer or other special case -START is the buffer position where the sexp starts." + "Get information about the current indentation context. +Context is returned in a cons with the form (STATUS . START). + +STATUS can be one of the following: + +keyword +------- + +:after-comment + - Point is after a comment line. + - START is the position of the \"#\" character. +:inside-string + - Point is inside string. + - START is the position of the first quote that starts it. +:no-indent + - No possible indentation case matches. + - START is always zero. + +:inside-paren + - Fallback case when point is inside paren. + - START is the first non space char position *after* the open paren. +:inside-paren-at-closing-nested-paren + - Point is on a line that contains a nested paren closer. + - START is the position of the open paren it closes. +:inside-paren-at-closing-paren + - Point is on a line that contains a paren closer. + - START is the position of the open paren. +:inside-paren-newline-start + - Point is inside a paren with items starting in their own line. + - START is the position of the open paren. +:inside-paren-newline-start-from-block + - Point is inside a paren with items starting in their own line + from a block start. + - START is the position of the open paren. + +:after-backslash + - Fallback case when point is after backslash. + - START is the char after the position of the backslash. +:after-backslash-assignment-continuation + - Point is after a backslashed assignment. + - START is the char after the position of the backslash. +:after-backslash-block-continuation + - Point is after a backslashed block continuation. + - START is the char after the position of the backslash. +:after-backslash-dotted-continuation + - Point is after a backslashed dotted continuation. Previous + line must contain a dot to align with. + - START is the char after the position of the backslash. +:after-backslash-first-line + - First line following a backslashed continuation. + - START is the char after the position of the backslash. + +:after-block-end + - Point is after a line containing a block ender. + - START is the position where the ender starts. +:after-block-start + - Point is after a line starting a block. + - START is the position where the block starts. +:after-line + - Point is after a simple line. + - START is the position where the previous line starts. +:at-dedenter-block-start + - Point is on a line starting a dedenter block. + - START is the position where the dedenter block starts." (save-restriction (widen) - (let ((ppss (save-excursion (beginning-of-line) (syntax-ppss))) - (start)) - (cons - (cond - ;; Beginning of buffer - ((save-excursion - (goto-char (line-beginning-position)) - (bobp)) - 'no-indent) - ;; Comment continuation - ((save-excursion - (when (and - (or - (python-info-current-line-comment-p) - (python-info-current-line-empty-p)) - (progn - (forward-comment -1) - (python-info-current-line-comment-p))) - (setq start (point)) - 'after-comment))) - ;; Inside string - ((setq start (python-syntax-context 'string ppss)) - 'inside-string) - ;; Inside a paren - ((setq start (python-syntax-context 'paren ppss)) - 'inside-paren) - ;; After backslash - ((setq start (when (not (or (python-syntax-context 'string ppss) - (python-syntax-context 'comment ppss))) - (let ((line-beg-pos (line-number-at-pos))) - (python-info-line-ends-backslash-p - (1- line-beg-pos))))) - 'after-backslash) - ;; After beginning of block - ((setq start (save-excursion - (when (progn - (back-to-indentation) - (python-util-forward-comment -1) - (equal (char-before) ?:)) - ;; Move to the first block start that's not in within - ;; a string, comment or paren and that's not a - ;; continuation line. - (while (and (re-search-backward - (python-rx block-start) nil t) - (or - (python-syntax-context-type) - (python-info-continuation-line-p)))) - (when (looking-at (python-rx block-start)) - (point-marker))))) - 'after-beginning-of-block) - ((when (setq start (python-info-dedenter-statement-p)) - 'dedenter-statement)) - ;; After normal line - ((setq start (save-excursion + (let ((ppss (save-excursion + (beginning-of-line) + (syntax-ppss)))) + (cond + ;; Beginning of buffer. + ((= (line-number-at-pos) 1) + (cons :no-indent 0)) + ;; Comment continuation (maybe). + ((save-excursion + (when (and + (or + (python-info-current-line-comment-p) + (python-info-current-line-empty-p)) + (forward-comment -1) + (python-info-current-line-comment-p)) + (cons :after-comment (point))))) + ;; Inside a string. + ((let ((start (python-syntax-context 'string ppss))) + (when start + (cons :inside-string start)))) + ;; Inside a paren. + ((let* ((start (python-syntax-context 'paren ppss)) + (starts-in-newline + (when start + (save-excursion + (goto-char start) + (forward-char) + (not + (= (line-number-at-pos) + (progn + (python-util-forward-comment) + (line-number-at-pos)))))))) + (when start + (cond + ;; Current line only holds the closing paren. + ((save-excursion + (skip-syntax-forward " ") + (when (and (python-syntax-closing-paren-p) + (progn + (forward-char 1) + (not (python-syntax-context 'paren)))) + (cons :inside-paren-at-closing-paren start)))) + ;; Current line only holds a closing paren for nested. + ((save-excursion + (back-to-indentation) + (python-syntax-closing-paren-p)) + (cons :inside-paren-at-closing-nested-paren start)) + ;; This line starts from a opening block in its own line. + ((save-excursion + (goto-char start) + (when (and + starts-in-newline + (save-excursion + (back-to-indentation) + (looking-at (python-rx block-start)))) + (cons + :inside-paren-newline-start-from-block start)))) + (starts-in-newline + (cons :inside-paren-newline-start start)) + ;; General case. + (t (cons :inside-paren + (save-excursion + (goto-char (1+ start)) + (skip-syntax-forward "(" 1) + (skip-syntax-forward " ") + (point)))))))) + ;; After backslash. + ((let ((start (when (not (python-syntax-comment-or-string-p ppss)) + (python-info-line-ends-backslash-p + (1- (line-number-at-pos)))))) + (when start + (cond + ;; Continuation of dotted expression. + ((save-excursion + (back-to-indentation) + (when (eq (char-after) ?\.) + ;; Move point back until it's not inside a paren. + (while (prog2 + (forward-line -1) + (and (not (bobp)) + (python-syntax-context 'paren)))) + (goto-char (line-end-position)) + (while (and (search-backward + "." (line-beginning-position) t) + (python-syntax-context-type))) + ;; Ensure previous statement has dot to align with. + (when (and (eq (char-after) ?\.) + (not (python-syntax-context-type))) + (cons :after-backslash-dotted-continuation (point)))))) + ;; Continuation of block definition. + ((let ((block-continuation-start + (python-info-block-continuation-line-p))) + (when block-continuation-start + (save-excursion + (goto-char block-continuation-start) + (re-search-forward + (python-rx block-start (* space)) + (line-end-position) t) + (cons :after-backslash-block-continuation (point)))))) + ;; Continuation of assignment. + ((let ((assignment-continuation-start + (python-info-assignment-continuation-line-p))) + (when assignment-continuation-start + (save-excursion + (goto-char assignment-continuation-start) + (cons :after-backslash-assignment-continuation (point)))))) + ;; First line after backslash continuation start. + ((save-excursion + (goto-char start) + (when (or (= (line-number-at-pos) 1) + (not (python-info-beginning-of-backslash + (1- (line-number-at-pos))))) + (cons :after-backslash-first-line start)))) + ;; General case. + (t (cons :after-backslash start)))))) + ;; After beginning of block. + ((let ((start (save-excursion + (back-to-indentation) + (python-util-forward-comment -1) + (when (equal (char-before) ?:) + (python-nav-beginning-of-block))))) + (when start + (cons :after-block-start start)))) + ;; At dedenter statement. + ((let ((start (python-info-dedenter-statement-p))) + (when start + (cons :at-dedenter-block-start start)))) + ;; After normal line. + ((let ((start (save-excursion (back-to-indentation) - (skip-chars-backward (rx (or whitespace ?\n))) + (skip-chars-backward " \t\n") (python-nav-beginning-of-statement) - (point-marker))) - 'after-line) - ;; Do not indent - (t 'no-indent)) - start)))) - -(defun python-indent-calculate-indentation () - "Calculate correct indentation offset for the current line. -Returns `noindent' if the indentation does not depend on Python syntax, -such as in strings." - (let* ((indentation-context (python-indent-context)) - (context-status (car indentation-context)) - (context-start (cdr indentation-context))) - (save-restriction - (widen) - (save-excursion - (pcase context-status - (`no-indent 0) - (`after-comment - (goto-char context-start) - (current-indentation)) - ;; When point is after beginning of block just add one level - ;; of indentation relative to the context-start - (`after-beginning-of-block - (goto-char context-start) - (+ (current-indentation) python-indent-offset)) - ;; When after a simple line just use previous line - ;; indentation. - (`after-line - (let* ((pair (save-excursion - (goto-char context-start) - (cons - (current-indentation) - (python-info-beginning-of-block-p)))) - (context-indentation (car pair)) - ;; TODO: Separate block enders into its own case. - (adjustment - (if (save-excursion - (python-util-forward-comment -1) - (python-nav-beginning-of-statement) - (looking-at (python-rx block-ender))) - python-indent-offset - 0))) - (- context-indentation adjustment))) - ;; When point is on a dedenter statement, search for the - ;; opening block that corresponds to it and use its - ;; indentation. If no opening block is found just remove - ;; indentation as this is an invalid python file. - (`dedenter-statement - (let ((block-start-point - (python-info-dedenter-opening-block-position))) - (save-excursion - (if (not block-start-point) - 0 - (goto-char block-start-point) - (current-indentation))))) - ;; When inside of a string, do nothing. just use the current - ;; indentation. XXX: perhaps it would be a good idea to - ;; invoke standard text indentation here - (`inside-string 'noindent) - ;; After backslash we have several possibilities. - (`after-backslash - (cond - ;; Check if current line is a dot continuation. For this - ;; the current line must start with a dot and previous - ;; line must contain a dot too. - ((save-excursion - (back-to-indentation) - (when (looking-at "\\.") - ;; If after moving one line back point is inside a paren it - ;; needs to move back until it's not anymore - (while (prog2 - (forward-line -1) - (and (not (bobp)) - (python-syntax-context 'paren)))) - (goto-char (line-end-position)) - (while (and (re-search-backward - "\\." (line-beginning-position) t) - (python-syntax-context-type))) - (if (and (looking-at "\\.") - (not (python-syntax-context-type))) - ;; The indentation is the same column of the - ;; first matching dot that's not inside a - ;; comment, a string or a paren - (current-column) - ;; No dot found on previous line, just add another - ;; indentation level. - (+ (current-indentation) python-indent-offset))))) - ;; Check if prev line is a block continuation - ((let ((block-continuation-start - (python-info-block-continuation-line-p))) - (when block-continuation-start - ;; If block-continuation-start is set jump to that - ;; marker and use first column after the block start - ;; as indentation value. - (goto-char block-continuation-start) - (re-search-forward - (python-rx block-start (* space)) - (line-end-position) t) - (current-column)))) - ;; Check if current line is an assignment continuation - ((let ((assignment-continuation-start - (python-info-assignment-continuation-line-p))) - (when assignment-continuation-start - ;; If assignment-continuation is set jump to that - ;; marker and use first column after the assignment - ;; operator as indentation value. - (goto-char assignment-continuation-start) - (current-column)))) - (t - (forward-line -1) - (goto-char (python-info-beginning-of-backslash)) - (if (save-excursion - (and - (forward-line -1) - (goto-char - (or (python-info-beginning-of-backslash) (point))) - (python-info-line-ends-backslash-p))) - ;; The two previous lines ended in a backslash so we must - ;; respect previous line indentation. - (current-indentation) - ;; What happens here is that we are dealing with the second - ;; line of a backslash continuation, in that case we just going - ;; to add one indentation level. - (+ (current-indentation) python-indent-offset))))) - ;; When inside a paren there's a need to handle nesting - ;; correctly - (`inside-paren - (cond - ;; If current line closes the outermost open paren use the - ;; current indentation of the context-start line. - ((save-excursion - (skip-syntax-forward "\s" (line-end-position)) - (when (and (looking-at (regexp-opt '(")" "]" "}"))) - (progn - (forward-char 1) - (not (python-syntax-context 'paren)))) - (goto-char context-start) - (current-indentation)))) - ;; If open paren is contained on a line by itself add another - ;; indentation level, else look for the first word after the - ;; opening paren and use it's column position as indentation - ;; level. - ((let* ((content-starts-in-newline) - (indent - (save-excursion - (if (setq content-starts-in-newline - (progn - (goto-char context-start) - (forward-char) - (save-restriction - (narrow-to-region - (line-beginning-position) - (line-end-position)) - (python-util-forward-comment)) - (looking-at "$"))) - (+ (current-indentation) python-indent-offset) - (current-column))))) - ;; Adjustments - (cond - ;; If current line closes a nested open paren de-indent one - ;; level. - ((progn - (back-to-indentation) - (looking-at (regexp-opt '(")" "]" "}")))) - (- indent python-indent-offset)) - ;; If the line of the opening paren that wraps the current - ;; line starts a block add another level of indentation to - ;; follow new pep8 recommendation. See: http://ur1.ca/5rojx - ((save-excursion - (when (and content-starts-in-newline - (progn - (goto-char context-start) - (back-to-indentation) - (looking-at (python-rx block-start)))) - (+ indent python-indent-offset)))) - (t indent))))))))))) - -(defun python-indent-calculate-levels () - "Calculate `python-indent-levels' and reset `python-indent-current-level'." - (if (or (python-info-continuation-line-p) - (not (python-info-dedenter-statement-p))) - ;; XXX: This asks for a refactor. Even if point is on a - ;; dedenter statement, it could be multiline and in that case - ;; the continuation lines should be indented with normal rules. - (let* ((indentation (python-indent-calculate-indentation))) - (if (not (numberp indentation)) - (setq python-indent-levels indentation) - (let* ((remainder (% indentation python-indent-offset)) - (steps (/ (- indentation remainder) python-indent-offset))) - (setq python-indent-levels (list 0)) - (dotimes (step steps) - (push (* python-indent-offset (1+ step)) python-indent-levels)) - (when (not (eq 0 remainder)) - (push (+ (* python-indent-offset steps) remainder) - python-indent-levels))))) - (setq python-indent-levels - (or - (mapcar (lambda (pos) - (save-excursion - (goto-char pos) - (current-indentation))) - (python-info-dedenter-opening-block-positions)) - (list 0)))) - (when (listp python-indent-levels) - (setq python-indent-current-level (1- (length python-indent-levels)) - python-indent-levels (nreverse python-indent-levels)))) - -(defun python-indent-toggle-levels () - "Toggle `python-indent-current-level' over `python-indent-levels'." - (setq python-indent-current-level (1- python-indent-current-level)) - (when (< python-indent-current-level 0) - (setq python-indent-current-level (1- (length python-indent-levels))))) - -(defun python-indent-line (&optional force-toggle) + (point)))) + (when start + (if (save-excursion + (python-util-forward-comment -1) + (python-nav-beginning-of-statement) + (looking-at (python-rx block-ender))) + (cons :after-block-end start) + (cons :after-line start))))) + ;; Default case: do not indent. + (t (cons :no-indent 0)))))) + +(defun python-indent--calculate-indentation () + "Internal implementation of `python-indent-calculate-indentation'. +May return an integer for the maximum possible indentation at +current context or a list of integers. The latter case is only +happening for :at-dedenter-block-start context since the +possibilities can be narrowed to especific indentation points." + (save-restriction + (widen) + (save-excursion + (pcase (python-indent-context) + (`(:no-indent . ,_) 0) + (`(,(or :after-line + :after-comment + :inside-string + :after-backslash + :inside-paren-at-closing-paren + :inside-paren-at-closing-nested-paren) . ,start) + ;; Copy previous indentation. + (goto-char start) + (current-indentation)) + (`(,(or :after-block-start + :after-backslash-first-line + :inside-paren-newline-start) . ,start) + ;; Add one indentation level. + (goto-char start) + (+ (current-indentation) python-indent-offset)) + (`(,(or :inside-paren + :after-backslash-block-continuation + :after-backslash-assignment-continuation + :after-backslash-dotted-continuation) . ,start) + ;; Use the column given by the context. + (goto-char start) + (current-column)) + (`(:after-block-end . ,start) + ;; Subtract one indentation level. + (goto-char start) + (- (current-indentation) python-indent-offset)) + (`(:at-dedenter-block-start . ,_) + ;; List all possible indentation levels from opening blocks. + (let ((opening-block-start-points + (python-info-dedenter-opening-block-positions))) + (if (not opening-block-start-points) + 0 ; if not found default to first column + (mapcar (lambda (pos) + (save-excursion + (goto-char pos) + (current-indentation))) + opening-block-start-points)))) + (`(,(or :inside-paren-newline-start-from-block) . ,start) + ;; Add two indentation levels to make the suite stand out. + (goto-char start) + (+ (current-indentation) (* python-indent-offset 2))))))) + +(defun python-indent--calculate-levels (indentation) + "Calculate levels list given INDENTATION. +Argument INDENTATION can either be an integer or a list of +integers. Levels are returned in ascending order, and in the +case INDENTATION is a list, this order is enforced." + (if (listp indentation) + (sort (copy-sequence indentation) #'<) + (let* ((remainder (% indentation python-indent-offset)) + (steps (/ (- indentation remainder) python-indent-offset)) + (levels (mapcar (lambda (step) + (* python-indent-offset step)) + (number-sequence steps 0 -1)))) + (reverse + (if (not (zerop remainder)) + (cons indentation levels) + levels))))) + +(defun python-indent--previous-level (levels indentation) + "Return previous level from LEVELS relative to INDENTATION." + (let* ((levels (sort (copy-sequence levels) #'>)) + (default (car levels))) + (catch 'return + (dolist (level levels) + (when (funcall #'< level indentation) + (throw 'return level))) + default))) + +(defun python-indent-calculate-indentation (&optional previous) + "Calculate indentation. +Get indentation of PREVIOUS level when argument is non-nil. +Return the max level of the cycle when indentation reaches the +minimum." + (let* ((indentation (python-indent--calculate-indentation)) + (levels (python-indent--calculate-levels indentation))) + (if previous + (python-indent--previous-level levels (current-indentation)) + (apply #'max levels)))) + +(defun python-indent-line (&optional previous) "Internal implementation of `python-indent-line-function'. -Uses the offset calculated in -`python-indent-calculate-indentation' and available levels -indicated by the variable `python-indent-levels' to set the -current indentation. +Use the PREVIOUS level when argument is non-nil, otherwise indent +to the maxium available level. When indentation is the minimum +possible and PREVIOUS is non-nil, cycle back to the maximum +level." + (let ((follow-indentation-p + ;; Check if point is within indentation. + (and (<= (line-beginning-position) (point)) + (>= (+ (line-beginning-position) + (current-indentation)) + (point))))) + (save-excursion + (indent-line-to + (python-indent-calculate-indentation previous)) + (python-info-dedenter-opening-block-message)) + (when follow-indentation-p + (back-to-indentation)))) -When the variable `last-command' is equal to one of the symbols -inside `python-indent-trigger-commands' or FORCE-TOGGLE is -non-nil it cycles levels indicated in the variable -`python-indent-levels' by setting the current level in the -variable `python-indent-current-level'. - -When the variable `last-command' is not equal to one of the -symbols inside `python-indent-trigger-commands' and FORCE-TOGGLE -is nil it calculates possible indentation levels and saves them -in the variable `python-indent-levels'. Afterwards it sets the -variable `python-indent-current-level' correctly so offset is -equal to - (nth python-indent-current-level python-indent-levels)" - (if (and (or (and (memq this-command python-indent-trigger-commands) - (eq last-command this-command)) - force-toggle) - (not (equal python-indent-levels '(0)))) - (if (listp python-indent-levels) - (python-indent-toggle-levels)) - (python-indent-calculate-levels)) - (if (eq python-indent-levels 'noindent) - python-indent-levels - (let* ((starting-pos (point-marker)) - (indent-ending-position - (+ (line-beginning-position) (current-indentation))) - (follow-indentation-p - (or (bolp) - (and (<= (line-beginning-position) starting-pos) - (>= indent-ending-position starting-pos)))) - (next-indent (nth python-indent-current-level python-indent-levels))) - (unless (= next-indent (current-indentation)) - (beginning-of-line) - (delete-horizontal-space) - (indent-to next-indent) - (goto-char starting-pos)) - (and follow-indentation-p (back-to-indentation))) - (python-info-dedenter-opening-block-message))) +(defun python-indent-calculate-levels () + "Return possible indentation levels." + (python-indent--calculate-levels + (python-indent--calculate-indentation))) (defun python-indent-line-function () "`indent-line-function' for Python mode. -See `python-indent-line' for details." - (python-indent-line)) +When the variable `last-command' is equal to one of the symbols +inside `python-indent-trigger-commands' it cycles possible +indentation levels from right to left." + (python-indent-line + (and (memq this-command python-indent-trigger-commands) + (eq last-command this-command)))) (defun python-indent-dedent-line () "De-indent current line." (interactive "*") - (when (and (not (python-syntax-comment-or-string-p)) - (<= (point) (save-excursion - (back-to-indentation) - (point))) - (> (current-column) 0)) - (python-indent-line t) - t)) + (when (and (not (bolp)) + (not (python-syntax-comment-or-string-p)) + (= (+ (line-beginning-position) + (current-indentation)) + (point))) + (python-indent-line t) + t)) (defun python-indent-dedent-line-backspace (arg) "De-indent current line. Argument ARG is passed to `backward-delete-char-untabify' when point is not in between the indentation." (interactive "*p") - (when (not (python-indent-dedent-line)) + (unless (python-indent-dedent-line) (backward-delete-char-untabify arg))) + (put 'python-indent-dedent-line-backspace 'delete-selection 'supersede) (defun python-indent-region (start end) diff --git a/lisp/progmodes/sh-script.el b/lisp/progmodes/sh-script.el index e8b6bf5adf7..135f945dbb9 100644 --- a/lisp/progmodes/sh-script.el +++ b/lisp/progmodes/sh-script.el @@ -1,7 +1,6 @@ ;;; sh-script.el --- shell-script editing commands for Emacs -*- lexical-binding:t -*- -;; Copyright (C) 1993-1997, 1999, 2001-2015 Free Software Foundation, -;; Inc. +;; Copyright (C) 1993-1997, 1999, 2001-2015 Free Software Foundation, Inc. ;; Author: Daniel Pfeiffer <occitan@esperanto.org> ;; Version: 2.0f @@ -1599,7 +1598,6 @@ buffer indents as it currently is indented. \\[backward-delete-char-untabify] Delete backward one position, even if it was a tab. -\\[newline-and-indent] Delete unquoted space and indent new line same as this one. \\[sh-end-of-command] Go to end of successive commands. \\[sh-beginning-of-command] Go to beginning of successive commands. \\[sh-set-shell] Set this buffer's shell, and maybe its magic number. @@ -2501,7 +2499,8 @@ Lines containing only comments are considered empty." (current-column))) current) (save-excursion - (indent-to (if (eq this-command 'newline-and-indent) + (indent-to (if (or (eq this-command 'newline-and-indent) + (and electric-indent-mode (eq this-command 'newline))) previous (if (< (current-column) (setq current (progn (back-to-indentation) diff --git a/lisp/subr.el b/lisp/subr.el index 05345853edc..68cd230c5e2 100644 --- a/lisp/subr.el +++ b/lisp/subr.el @@ -1082,7 +1082,12 @@ The return value is a positive integer." ;;;; Extracting fields of the positions in an event. (defun posnp (obj) - "Return non-nil if OBJ appears to be a valid `posn' object." + "Return non-nil if OBJ appears to be a valid `posn' object specifying a window. +If OBJ is a valid `posn' object, but specifies a frame rather +than a window, return nil." + ;; FIXME: Correct the behavior of this function so that all valid + ;; `posn' objects are recognized, after updating other code that + ;; depends on its present behavior. (and (windowp (car-safe obj)) (atom (car-safe (setq obj (cdr obj)))) ;AREA-OR-POS. (integerp (car-safe (car-safe (setq obj (cdr obj))))) ;XOFFSET. @@ -1142,24 +1147,28 @@ For a scroll-bar event, the result column is 0, and the row corresponds to the vertical position of the click in the scroll bar. POSITION should be a list of the form returned by the `event-start' and `event-end' functions." - (let* ((pair (posn-x-y position)) - (window (posn-window position)) - (area (posn-area position))) + (let* ((pair (posn-x-y position)) + (frame-or-window (posn-window position)) + (frame (if (framep frame-or-window) + frame-or-window + (window-frame frame-or-window))) + (window (when (windowp frame-or-window) frame-or-window)) + (area (posn-area position))) (cond - ((null window) + ((null frame-or-window) '(0 . 0)) ((eq area 'vertical-scroll-bar) (cons 0 (scroll-bar-scale pair (1- (window-height window))))) ((eq area 'horizontal-scroll-bar) (cons (scroll-bar-scale pair (window-width window)) 0)) (t - (let* ((frame (if (framep window) window (window-frame window))) - ;; FIXME: This should take line-spacing properties on - ;; newlines into account. - (spacing (when (display-graphic-p frame) - (or (with-current-buffer (window-buffer window) - line-spacing) - (frame-parameter frame 'line-spacing))))) + ;; FIXME: This should take line-spacing properties on + ;; newlines into account. + (let* ((spacing (when (display-graphic-p frame) + (or (with-current-buffer + (window-buffer (frame-selected-window frame)) + line-spacing) + (frame-parameter frame 'line-spacing))))) (cond ((floatp spacing) (setq spacing (truncate (* spacing (frame-char-height frame))))) diff --git a/lisp/textmodes/artist.el b/lisp/textmodes/artist.el index 8a2383c12ff..85d9410868a 100644 --- a/lisp/textmodes/artist.el +++ b/lisp/textmodes/artist.el @@ -4963,52 +4963,55 @@ The event, EV, is the mouse event." (artist-funcall init-fn x1 y1) (if (not artist-rubber-banding) (artist-no-rb-set-point1 x1 y1)) - (track-mouse - (while (or (mouse-movement-p ev) - (member 'down (event-modifiers ev))) - (setq ev-start-pos (artist-coord-win-to-buf - (posn-col-row (event-start ev)))) - (setq x1 (car ev-start-pos)) - (setq y1 (cdr ev-start-pos)) - - ;; Cancel previous timer - (if timer - (cancel-timer timer)) - - (if (not (eq initial-win (posn-window (event-start ev)))) - ;; If we moved outside the window, do nothing - nil - - ;; Still in same window: - ;; - ;; Check if user presses or releases shift key - (if (artist-shift-has-changed shift-state ev) - - ;; First check that the draw-how is the same as we - ;; already have. Otherwise, ignore the changed shift-state. - (if (not (eq draw-how - (artist-go-get-draw-how-from-symbol - (if (not shift-state) shifted unshifted)))) - (message "Cannot switch to shifted operation") - - ;; progn is "implicit" since this is the else-part - (setq shift-state (not shift-state)) - (setq op (if shift-state shifted unshifted)) - (setq draw-how (artist-go-get-draw-how-from-symbol op)) - (setq draw-fn (artist-go-get-draw-fn-from-symbol op)))) - - ;; Draw the new shape - (setq shape (artist-funcall draw-fn x1 y1)) - (artist-move-to-xy x1 y1) - - ;; Start the timer to call `draw-fn' repeatedly every - ;; `interval' second - (if (and interval draw-fn) - (setq timer (run-at-time interval interval draw-fn x1 y1)))) - - ;; Read next event - (setq ev (read-event)))) - + (unwind-protect + (track-mouse + (while (or (mouse-movement-p ev) + (member 'down (event-modifiers ev))) + (setq ev-start-pos (artist-coord-win-to-buf + (posn-col-row (event-start ev)))) + (setq x1 (car ev-start-pos)) + (setq y1 (cdr ev-start-pos)) + + ;; Cancel previous timer + (if timer + (cancel-timer timer)) + + (if (not (eq initial-win (posn-window (event-start ev)))) + ;; If we moved outside the window, do nothing + nil + + ;; Still in same window: + ;; + ;; Check if user presses or releases shift key + (if (artist-shift-has-changed shift-state ev) + + ;; First check that the draw-how is the same as we + ;; already have. Otherwise, ignore the changed shift-state. + (if (not (eq draw-how + (artist-go-get-draw-how-from-symbol + (if (not shift-state) shifted unshifted)))) + (message "Cannot switch to shifted operation") + + ;; progn is "implicit" since this is the else-part + (setq shift-state (not shift-state)) + (setq op (if shift-state shifted unshifted)) + (setq draw-how (artist-go-get-draw-how-from-symbol op)) + (setq draw-fn (artist-go-get-draw-fn-from-symbol op)))) + + ;; Draw the new shape + (setq shape (artist-funcall draw-fn x1 y1)) + (artist-move-to-xy x1 y1) + + ;; Start the timer to call `draw-fn' repeatedly every + ;; `interval' second + (if (and interval draw-fn) + (setq timer (run-at-time interval interval draw-fn x1 y1)))) + + ;; Read next event + (setq ev (read-event)))) + ;; Cleanup: get rid of any active timer. + (if timer + (cancel-timer timer))) ;; Cancel any timers (if timer (cancel-timer timer)) diff --git a/lisp/w32-common-fns.el b/lisp/w32-common-fns.el new file mode 100644 index 00000000000..1e4e9fe5bb1 --- /dev/null +++ b/lisp/w32-common-fns.el @@ -0,0 +1,134 @@ +;;; w32-common-fns.el --- Lisp routines for Windows and Cygwin-w32 + +;; Copyright (C) 1994, 2001-2015 Free Software Foundation, Inc. + +;; 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 file contains functions that are used by both native NT Emacs +;;; and Cygwin Emacs compiled to use the native Windows widget +;;; library. + +(declare-function x-server-version "w32fns.c" (&optional terminal)) + +(defun w32-version () + "Return the MS-Windows version numbers. +The value is a list of three integers: the major and minor version +numbers, and the build number." + (x-server-version)) + +(defun w32-using-nt () + "Return non-nil if running on a Windows NT descendant. +That includes all Windows systems except for 9X/Me." + (getenv "SystemRoot")) + +(declare-function w32-get-clipboard-data "w32select.c") +(declare-function w32-set-clipboard-data "w32select.c") +(declare-function x-server-version "w32fns.c" (&optional display)) + +;;; Fix interface to (X-specific) mouse.el +(defun x-set-selection (type data) + "Make an X selection of type TYPE and value DATA. +The argument TYPE (nil means `PRIMARY') says which selection, and +DATA specifies the contents. TYPE must be a symbol. \(It can also +be a string, which stands for the symbol with that name, but this +is considered obsolete.) DATA may be a string, a symbol, an +integer (or a cons of two integers or list of two integers). + +The selection may also be a cons of two markers pointing to the same buffer, +or an overlay. In these cases, the selection is considered to be the text +between the markers *at whatever time the selection is examined*. +Thus, editing done in the buffer after you specify the selection +can alter the effective value of the selection. + +The data may also be a vector of valid non-vector selection values. + +The return value is DATA. + +Interactively, this command sets the primary selection. Without +prefix argument, it reads the selection in the minibuffer. With +prefix argument, it uses the text of the region as the selection value. + +Note that on MS-Windows, primary and secondary selections set by Emacs +are not available to other programs." + (put 'x-selections (or type 'PRIMARY) data)) + +(defun x-get-selection (&optional type _data-type) + "Return the value of an X Windows selection. +The argument TYPE (default `PRIMARY') says which selection, +and the argument DATA-TYPE (default `STRING') says +how to convert the data. + +TYPE may be any symbol \(but nil stands for `PRIMARY'). However, +only a few symbols are commonly used. They conventionally have +all upper-case names. The most often used ones, in addition to +`PRIMARY', are `SECONDARY' and `CLIPBOARD'. + +DATA-TYPE is usually `STRING', but can also be one of the symbols +in `selection-converter-alist', which see. This argument is +ignored on MS-Windows and MS-DOS." + (get 'x-selections (or type 'PRIMARY))) + +;; x-selection-owner-p is used in simple.el +(defun x-selection-owner-p (&optional selection _terminal) + "" ; placeholder for doc.c + (and (memq selection '(nil PRIMARY SECONDARY)) + (get 'x-selections (or selection 'PRIMARY)))) + +;; The "Windows" keys on newer keyboards bring up the Start menu +;; whether you want it or not - make Emacs ignore these keystrokes +;; rather than beep. +(global-set-key [lwindow] 'ignore) +(global-set-key [rwindow] 'ignore) + +(defvar w32-charset-info-alist) ; w32font.c + + +;;;; Selections + +;; We keep track of the last text selected here, so we can check the +;; current selection against it, and avoid passing back our own text +;; from x-selection-value. +(defvar x-last-selected-text nil) +(defvar x-select-enable-clipboard) + +(defun x-get-selection-value () + "Return the value of the current selection. +Consult the selection. Treat empty strings as if they were unset." + (if x-select-enable-clipboard + (let (text) + ;; Don't die if x-get-selection signals an error. + (with-demoted-errors "w32-get-clipboard-data:%s" + (setq text (w32-get-clipboard-data))) + (if (string= text "") (setq text nil)) + (cond + ((not text) nil) + ((eq text x-last-selected-text) nil) + ((string= text x-last-selected-text) + ;; Record the newer string, so subsequent calls can use the 'eq' test. + (setq x-last-selected-text text) + nil) + (t + (setq x-last-selected-text text)))))) + +(defalias 'x-selection-value 'x-get-selection-value) + +;; Arrange for the kill and yank functions to set and check the clipboard. +(setq interprogram-cut-function 'x-select-text) +(setq interprogram-paste-function 'x-get-selection-value) + +(provide 'w32-common-fns) |