summaryrefslogtreecommitdiff
path: root/lisp
diff options
context:
space:
mode:
Diffstat (limited to 'lisp')
-rw-r--r--lisp/ChangeLog68
-rw-r--r--lisp/button.el20
-rw-r--r--lisp/erc/ChangeLog5
-rw-r--r--lisp/erc/erc-backend.el7
-rw-r--r--lisp/filenotify.el383
-rw-r--r--lisp/files.el8
-rw-r--r--lisp/gnus/gnus-setup.el191
-rw-r--r--lisp/net/net-utils.el20
-rw-r--r--lisp/net/tramp.el3
-rw-r--r--lisp/progmodes/cap-words.el98
-rw-r--r--lisp/progmodes/python.el702
-rw-r--r--lisp/progmodes/sh-script.el7
-rw-r--r--lisp/subr.el33
-rw-r--r--lisp/textmodes/artist.el95
-rw-r--r--lisp/w32-common-fns.el134
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)