unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#8754: submission of vimvars
       [not found] <BANLkTikYHe-dgUUbv1ZW+HNF4AvO9fNB8g@mail.gmail.com>
@ 2011-05-28 22:39 ` James Youngman
  2011-05-29  8:25   ` Štěpán Němec
                     ` (3 more replies)
  0 siblings, 4 replies; 12+ messages in thread
From: James Youngman @ 2011-05-28 22:39 UTC (permalink / raw)
  To: 8754

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

Sorry, I'm attaching the patch instead of sending it inline, contrary
to the contribution guidelines, but I'll include the commit message
inline.  Google already has an FSF copyright assignment for Emacs;
fwiw, so do I.   Feedback on the right place in the manual to document
this would be particularly welcome, since I wasn't certain which the
optimal spot was.


 Add new module vimvars

 * emulation/vimvars.el: New file; supports "vi: set foo" mode
 lines in vi, ex, vim and similar editors.
 * custom.texi (vi-compatible modeline): New section describing vimvars.
 * misc.texi (Emulation): Mention vimvars.
 * NEWS: Mention addition of vimvars.el.

-- 
Google Ireland Ltd., Gordon House, Barrow Street, Dublin 4, Ireland
Registered in Dublin, Ireland.  Registration Number: 368047
http://tinyurl.com/345mmx

[-- Attachment #2: vimvars-submit.diff --]
[-- Type: text/x-patch, Size: 11215 bytes --]

------------------------------------------------------------
revno: 104398
committer: James Youngman <youngman@google.com>
branch nick: jy-contrib-vimvars
timestamp: Sat 2011-05-28 20:56:40 +0100
message:
  Add new module vimvars
  
  * emulation/vimvars.el: New file; supports "vi: set foo" mode
  lines in vi, ex, vim and similar editors.
  * custom.texi (vi-compatible modeline): New section describing vimvars.
  * misc.texi (Emulation): Mention vimvars.
  * NEWS: Mention addition of vimvars.el.
diff:
=== modified file 'doc/emacs/ChangeLog'
--- doc/emacs/ChangeLog	2011-05-27 01:00:53 +0000
+++ doc/emacs/ChangeLog	2011-05-28 19:56:40 +0000
@@ -1,3 +1,8 @@
+2011-05-28  James Youngman  <youngman@google.com>
+
+	* custom.texi (vi-compatible modeline): New section describing vimvars.
+	* misc.texi (Emulation): Mention vimvars.
+
 2011-05-27  Glenn Morris  <rgm@gnu.org>
 
 	* custom.texi (Specifying File Variables):

=== modified file 'doc/emacs/custom.texi'
--- doc/emacs/custom.texi	2011-05-27 01:00:53 +0000
+++ doc/emacs/custom.texi	2011-05-28 19:56:40 +0000
@@ -1069,6 +1069,7 @@
 @menu
 * Specifying File Variables:: Specifying file local variables.
 * Safe File Variables::       Making sure file local variables are safe.
+* vi-compatible modeline::    Support for vi modelines.
 @end menu
 
 @node Specifying File Variables
@@ -1287,6 +1288,29 @@
 @code{eval} form if that form occurs within the variable
 @code{safe-local-eval-forms}.
 
+@node vi-compatible modeline
+@subsubsection Support for vi modelines
+
+The vi editor also supports a feature like local variables.  Emacs can
+understand these too.  To enable this feature, evaluate this Lisp
+expression (in the @file{.emacs} file, for example):
+
+@example
+(require 'vimvars)
+(add-hook 'find-file-hook 
+          'vimvars-obey-vim-modeline) 
+@end example
+
+Some of the vi modeline settings make no sense for Emacs and so are
+not supported.  Others are partially supported; for example, @samp{vi:
+set shiftwidth=N} is supported only in c-mode.
+
+Only the first @code{vimvars-check-lines} lines of a file are checked
+for a vi mode line. If a file contains both Emacs local variables and
+a vi modeline, the vi modeline will be ignored.  You can change this
+by setting @code{vimvars-ignore-mode-line-if-local-variables-exist} to
+@code{nil}.
+
 @node Directory Variables
 @subsection Per-Directory Local Variables
 @cindex local variables, for all files in a directory

=== modified file 'doc/emacs/misc.texi'
--- doc/emacs/misc.texi	2011-05-17 02:26:56 +0000
+++ doc/emacs/misc.texi	2011-05-28 19:56:40 +0000
@@ -2556,6 +2556,21 @@
 
 @inforef{Top, VIP, vip}, for full information.
 
+@item vimvars (support for vi mode lines)
+Emacs can understand many of the ``modeline'' configurations that
+vi-compatible editors do.  
+@xref{vi-compatible modeline,,Support for vi modelines}.
+
+
+To enable this feature, evaluate this Lisp
+expression:
+
+@example
+(require 'vimvars)
+(add-hook 'find-file-hook 
+          'vimvars-obey-vim-modeline) 
+@end example
+
 @item WordStar (old wordprocessor)
 @findex wordstar-mode
 @kbd{M-x wordstar-mode} provides a major mode with WordStar-like

=== modified file 'etc/ChangeLog'
--- etc/ChangeLog	2011-05-24 14:22:44 +0000
+++ etc/ChangeLog	2011-05-28 19:56:40 +0000
@@ -1,3 +1,7 @@
+2011-05-28  James Youngman  <youngman@google.com>
+
+	* NEWS: Mention addition of vimvars.el.
+
 2011-05-24  Leo Liu  <sdl.web@gmail.com>
 
 	* NEWS: Mention the new primitive sha1 and the removal of sha1.el.

=== modified file 'etc/NEWS'
--- etc/NEWS	2011-05-27 01:00:53 +0000
+++ etc/NEWS	2011-05-28 19:56:40 +0000
@@ -769,6 +769,11 @@
 
 ** xmodmap-generic-mode for xmodmap files.
 
+** vimvvars.el provides support for vi mode lines
+See "Support for vi modelines" in the Emacs Manual for the
+documentation.
+
+
 \f
 * Incompatible Lisp Changes in Emacs 24.1
 

=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2011-05-28 02:10:32 +0000
+++ lisp/ChangeLog	2011-05-28 19:56:40 +0000
@@ -1,3 +1,8 @@
+2011-05-28  James Youngman  <youngman@google.com>
+
+	* emulation/vimvars.el: New file; supports "vi: set foo" mode
+	lines in vi, ex, vim and similar editors.
+
 2011-05-28  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* minibuffer.el (completion--capf-wrapper): Check applicability before

=== added file 'lisp/emulation/vimvars.el'
--- lisp/emulation/vimvars.el	1970-01-01 00:00:00 +0000
+++ lisp/emulation/vimvars.el	2011-05-28 19:56:40 +0000
@@ -0,0 +1,176 @@
+;;; vimvars.el --- Emacs support for VI modelines
+
+;; Copyright (C) 2010 Free Software Foundation, Inc.
+
+;; Author: James Youngman <youngman@google.com>
+;; Maintainer: James Youngman <youngman@google.com>
+;; Keywords: local-variables, vi, vim, emulations
+
+;; vimvars 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.
+
+;; vimvars 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 vimvars.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Defines a function `vimvars-obey-vim-modeline' which is suitable for
+;; a hook which checks for a VI-style in the current buffer and sets
+;; various Emacs buffer-local variables accordingly.
+
+;;; Code:
+
+(defgroup vimvars nil
+  "Support for VIM mode lines."
+  :group 'find-file)
+
+
+(defcustom vimvars-enabled t
+  "If nil, VIM mode lines will be ignored."
+  :type 'boolean
+  :group 'vimvars)
+(make-variable-buffer-local 'vimvars-enabled)
+
+
+(defcustom vimvars-check-lines 5
+  "The number of lines in the head of a file that we will search for VIM settings (VIM itself checks 5)."
+  :type 'integer
+  :group 'vimvars)
+
+
+(defcustom vimvars-ignore-mode-line-if-local-variables-exist t
+  "If non-nil, VIM mode lines are ignored in files that have Emacs local variables."
+  :type 'boolean
+  :group 'vimvars)
+
+
+;; It appears that real VIM accepts backslash-escaped characters (for
+;; example \\| inside makeprg).
+;;
+;; Also, VIM accepts vi: and vim: at start-of line (but not ex:)
+;;
+;; Google Code search can be helpful in assessing what options are widely used,
+;; for example see
+;; <http://codesearch.google.com/codesearch?q=(ex|vim%3F):\+(se\+|setlocal)>
+(defconst vimvars-modeline-re
+  "\\(^\\|[ 	]\\)\\(ex\\|vim?\\):[	 ]?\\(set\\|setlocal\\|se\\)? \\([^:]+\\):"
+  "Regex matching a VIM modeline.")
+
+
+(defun vimvars-should-obey-modeline ()
+  "Return non-nil if a VIM modeline should be obeyed in this file."
+  ;; Always return nil if vimvars-enabled is nil.
+  ;; Otherwise, if there are Emacs local variables for this file,
+  ;; return nil unless vimvars-ignore-mode-line-if-local-variables-exist
+  ;; is also nil.
+  (when vimvars-enabled
+    (if file-local-variables-alist
+        (not vimvars-ignore-mode-line-if-local-variables-exist)
+      t)))
+
+  
+(defun vimvars-accept-tag (leader tag)
+  "Return non-nil if LEADER followed by TAG should be accepted as a modeline."
+  (cond
+   ((equal "vim" tag) t)
+   ((equal "vi" tag) t)
+   ;; Accept "ex:" only when it is not at the beginning of a line.
+   ((equal "ex" tag) (not (equal 0 (length leader))))
+   (t nil)))
+
+
+(defun vimvars-obey-vim-modeline ()
+  "Check the top of a file for VIM-style settings, and obey them.
+Only the first `vimvars-chars-in-file-head' characters of the file
+are checked for VIM variables.   You can use this in `find-file-hook'."
+  (when (vimvars-should-obey-modeline)
+    (save-excursion
+      ;; Look for something like this: vi: set sw=4 ts=4:
+      ;; We should look for it in a comment, but for now
+      ;; we won't worry about the syntax of the major mode.
+      (goto-char (point-min))
+      (if (and
+           (re-search-forward vimvars-modeline-re
+		  (line-end-position vimvars-check-lines) t)
+           (vimvars-accept-tag (match-string 1) (match-string 2)))
+          (progn
+            (message "found a modeline: %s" (match-string 0))
+            (let ((settings-end (match-end 4)))
+	;; We ignore the local suffix, since for Emacs
+	;; most settings will be buffer-local anyway.
+	;;(message "found VIM settings %s" (match-string 4))
+	(goto-char (match-beginning 4))
+	(while (re-search-forward
+	        " *\\([^= ]+\\)\\(=\\([^ :]+\\)\\)?" settings-end t)
+	  (let ((variable (vimvars-expand-option-name (match-string 1))))
+	    (if (match-string 3)
+	        (vimvars-assign variable (match-string 3))
+	      (vimvars-enable-feature variable))))))))))
+
+
+(defun vimvars-set-indent (indent)
+  "Set the amount of indentation caused by tab to INDENT in a mode-aware way."
+  (when (equal major-mode 'c-mode) (setq c-basic-offset indent)))
+
+
+(defun vimvars-expand-option-name (option)
+  "Expand the abbreviated VIM :set variable OPTION to its full name."
+  (let ((expansion
+	 (assoc option
+		'(("ro" "readonly")
+		  ("sts" "softtabstop")
+		  ("sw" "shiftwidth")
+		  ("ts" "tabstop")
+		  ("tw" "textwidth")))))
+    (if expansion (cadr expansion) option)))
+   
+
+;;; Not supported:
+;;; comments/com (comment leader), because it's not language-specific in VIM.
+(defun vimvars-assign (var val)
+  "Emulate VIM's :set VAR=VAL."
+  (message "Setting VIM option %s to %s in %s" var val (buffer-name))
+  (cond
+   ((equal var "makeprg") (setq compile-command val))
+   ((equal var "shiftwidth") (vimvars-set-indent (string-to-number val)))
+   ((equal var "softtabstop") t) ; Ignore.
+   ((equal var "tabstop") (setq tab-width (string-to-number val)))
+   ((equal var "textwidth") (set-fill-column (string-to-number val)))
+   (t (message "Don't know how to emulate VIM variable %s" var))))
+
+
+;; FIXME: Also consider supporting ...
+;; fileencoding, encoding could be useful but likely too hairy
+;; fileformat
+;; tags
+;; textmode (but this is obsolete in VIM, replaced by fileformat)
+;; Not supported:
+;; bomb/nobomd (byte order mark control), because I don't expect it is
+;; comonly enough used to justify the maintenance burden.
+(defun vimvars-enable-feature (var)
+  "Emulate VIM's :set VAR for a variables that are just boolean."
+  (message "Enabling VIM option %s in %s" var (buffer-name))
+  (cond
+   ((equal var "expandtab") (setq indent-tabs-mode nil))
+   ((equal var "ignorecase") (setq case-fold-search t))
+   ((equal var "readonly") (toggle-read-only 1))
+   ((equal var "wrap") (setq truncate-lines nil))
+   ((equal var "write") (toggle-read-only -1)) ; Similar, not the same.
+   
+   ((equal var "noexpandtab") (setq indent-tabs-mode t))
+   ((equal var "noignorecase") (setq case-fold-search nil))
+   ((equal var "noreadonly") (toggle-read-only -1))
+   ((equal var "nowrap") (setq truncate-lines t))
+   ((equal var "nowrite") (toggle-read-only 1)) ; Similar, not the same
+
+   (t (message "Don't know how to emulate VIM feature %s" var))))
+
+(provide 'vimvars)
+;;; vimvars.el ends here

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

* bug#8754: submission of vimvars
  2011-05-28 22:39 ` bug#8754: submission of vimvars James Youngman
@ 2011-05-29  8:25   ` Štěpán Němec
  2011-06-14 16:27     ` James Youngman
  2011-05-29 17:21   ` Nix
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 12+ messages in thread
From: Štěpán Němec @ 2011-05-29  8:25 UTC (permalink / raw)
  To: James Youngman; +Cc: 8754

James Youngman <youngman@google.com> writes:

Just one note:

> +Only the first @code{vimvars-check-lines} lines of a file are checked
> +for a vi mode line. If a file contains both Emacs local variables and

Vim also checks N last lines of a file. Actually I'd say it's (much)
more common to have a Vim mode line at the end than at the beginning.

  Štěpán

P.S.: There was also this package with a similar goal last time I
looked:

  http://bitbucket.org/danderson/evimodeline
  
Do you know about that one?





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

* bug#8754: submission of vimvars
  2011-05-28 22:39 ` bug#8754: submission of vimvars James Youngman
  2011-05-29  8:25   ` Štěpán Němec
@ 2011-05-29 17:21   ` Nix
  2011-05-29 18:05     ` James Youngman
  2011-06-14 16:11   ` James Youngman
  2011-07-06 13:12   ` Stefan Monnier
  3 siblings, 1 reply; 12+ messages in thread
From: Nix @ 2011-05-29 17:21 UTC (permalink / raw)
  To: James Youngman; +Cc: 8754

On 28 May 2011, James Youngman stated:

> +(defun vimvars-enable-feature (var)
> +  "Emulate VIM's :set VAR for a variables that are just boolean."

Nit-pick of the day: excess 'a'.





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

* bug#8754: submission of vimvars
  2011-05-29 17:21   ` Nix
@ 2011-05-29 18:05     ` James Youngman
  0 siblings, 0 replies; 12+ messages in thread
From: James Youngman @ 2011-05-29 18:05 UTC (permalink / raw)
  To: Nix, stepnem; +Cc: 8754

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

On Sun, May 29, 2011 at 18:21, Nix <nix@esperi.org.uk> wrote:
> On 28 May 2011, James Youngman stated:
>
>> +(defun vimvars-enable-feature (var)
>> +  "Emulate VIM's :set VAR for a variables that are just boolean."
>
> Nit-pick of the day: excess 'a'.

Thanks for catching that.   Thanks also to Štěpán for pointing out
that we need to check the bottom of the file too.   Here's an updated
patch fixing both of those problems.

James.

[-- Attachment #2: vimvars-second-submit.diff --]
[-- Type: text/x-patch, Size: 12383 bytes --]

=== modified file 'doc/emacs/ChangeLog'
--- doc/emacs/ChangeLog	2011-05-27 01:00:53 +0000
+++ doc/emacs/ChangeLog	2011-05-29 18:00:23 +0000
@@ -1,3 +1,13 @@
+2011-05-29  James Youngman  <jay@gnu.org>
+
+	* custom.texi: Vimvars will now find a mode line in the end of the
+	file too.
+
+2011-05-28  James Youngman  <youngman@google.com>
+
+	* custom.texi (vi-compatible modeline): New section describing vimvars.
+	* misc.texi (Emulation): Mention vimvars.
+
 2011-05-27  Glenn Morris  <rgm@gnu.org>
 
 	* custom.texi (Specifying File Variables):

=== modified file 'doc/emacs/custom.texi'
--- doc/emacs/custom.texi	2011-05-27 01:00:53 +0000
+++ doc/emacs/custom.texi	2011-05-29 17:59:40 +0000
@@ -1069,6 +1069,7 @@
 @menu
 * Specifying File Variables:: Specifying file local variables.
 * Safe File Variables::       Making sure file local variables are safe.
+* vi-compatible modeline::    Support for vi modelines.
 @end menu
 
 @node Specifying File Variables
@@ -1287,6 +1288,30 @@
 @code{eval} form if that form occurs within the variable
 @code{safe-local-eval-forms}.
 
+@node vi-compatible modeline
+@subsubsection Support for vi modelines
+
+The vi editor also supports a feature like local variables.  Emacs can
+understand these too.  To enable this feature, evaluate this Lisp
+expression (in the @file{.emacs} file, for example):
+
+@example
+(require 'vimvars)
+(add-hook 'find-file-hook 
+          'vimvars-obey-vim-modeline) 
+@end example
+
+Some of the vi modeline settings make no sense for Emacs and so are
+not supported.  Others are partially supported; for example, @samp{vi:
+set shiftwidth=N} is supported only in c-mode.
+
+Only the first and last @code{vimvars-check-lines} lines of a file are
+checked for a vi mode line. If a file contains both Emacs local
+variables and a vi modeline, the vi modeline will be ignored.  You can
+change this by setting
+@code{vimvars-ignore-mode-line-if-local-variables-exist} to
+@code{nil}.
+
 @node Directory Variables
 @subsection Per-Directory Local Variables
 @cindex local variables, for all files in a directory

=== modified file 'doc/emacs/misc.texi'
--- doc/emacs/misc.texi	2011-05-17 02:26:56 +0000
+++ doc/emacs/misc.texi	2011-05-28 21:17:38 +0000
@@ -2556,6 +2556,21 @@
 
 @inforef{Top, VIP, vip}, for full information.
 
+@item vimvars (support for vi mode lines)
+Emacs can understand many of the ``modeline'' configurations that
+vi-compatible editors do.  
+@xref{vi-compatible modeline,,Support for vi modelines}.
+
+
+To enable this feature, evaluate this Lisp
+expression:
+
+@example
+(require 'vimvars)
+(add-hook 'find-file-hook 
+          'vimvars-obey-vim-modeline) 
+@end example
+
 @item WordStar (old wordprocessor)
 @findex wordstar-mode
 @kbd{M-x wordstar-mode} provides a major mode with WordStar-like

=== modified file 'etc/ChangeLog'
--- etc/ChangeLog	2011-05-24 14:22:44 +0000
+++ etc/ChangeLog	2011-05-28 21:17:38 +0000
@@ -1,3 +1,7 @@
+2011-05-28  James Youngman  <youngman@google.com>
+
+	* NEWS: Mention addition of vimvars.el.
+
 2011-05-24  Leo Liu  <sdl.web@gmail.com>
 
 	* NEWS: Mention the new primitive sha1 and the removal of sha1.el.

=== modified file 'etc/NEWS'
--- etc/NEWS	2011-05-27 01:00:53 +0000
+++ etc/NEWS	2011-05-28 21:17:38 +0000
@@ -769,6 +769,11 @@
 
 ** xmodmap-generic-mode for xmodmap files.
 
+** vimvvars.el provides support for vi mode lines
+See "Support for vi modelines" in the Emacs Manual for the
+documentation.
+
+
 \f
 * Incompatible Lisp Changes in Emacs 24.1
 

=== modified file 'lisp/ChangeLog'
--- lisp/ChangeLog	2011-05-28 02:10:32 +0000
+++ lisp/ChangeLog	2011-05-29 18:01:37 +0000
@@ -1,3 +1,24 @@
+2011-05-29  James Youngman  <jay@gnu.org>
+
+	* emulation/vimvars.el (vimvars-check-lines): We also check
+	vimvars-check-lines lines at the bottom of the file.
+	(vimvars-obey-this-vim-modeline): Factor out of
+	vimvars-obey-vim-modeline in order to separate the concerns of
+	finding the modeline and obeying it.
+	(vimvars-obey-top-modeline): New function, locates a modeline at
+	the top of the file.
+	(vimvars-obey-bottom-modeline): New function, locates a modeline
+	at the bottom of the file.
+	(vimvars-obey-vim-modeline): Move some of the body into
+	vimvars-obey-this-vim-modeline.  Call vimvars-obey-top-modeline
+	and (if it fails to find a modeline) vimvars-obey-bottom-modeline.
+	(vimvars-enable-feature): Fix typo in docstring.
+
+2011-05-28  James Youngman  <youngman@google.com>
+
+	* emulation/vimvars.el: New file; supports "vi: set foo" mode
+	lines in vi, ex, vim and similar editors.
+
 2011-05-28  Stefan Monnier  <monnier@iro.umontreal.ca>
 
 	* minibuffer.el (completion--capf-wrapper): Check applicability before

=== added file 'lisp/emulation/vimvars.el'
--- lisp/emulation/vimvars.el	1970-01-01 00:00:00 +0000
+++ lisp/emulation/vimvars.el	2011-05-29 17:56:50 +0000
@@ -0,0 +1,201 @@
+;;; vimvars.el --- Emacs support for VI modelines
+
+;; Copyright (C) 2010 Free Software Foundation, Inc.
+
+;; Author: James Youngman <youngman@google.com>
+;; Maintainer: James Youngman <youngman@google.com>
+;; Keywords: local-variables, vi, vim, emulations
+
+;; vimvars 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.
+
+;; vimvars 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 vimvars.  If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;; Defines a function `vimvars-obey-vim-modeline' which is suitable for
+;; a hook which checks for a VI-style in the current buffer and sets
+;; various Emacs buffer-local variables accordingly.
+
+;;; Code:
+
+(defgroup vimvars nil
+  "Support for VIM mode lines."
+  :group 'find-file)
+
+
+(defcustom vimvars-enabled t
+  "If nil, VIM mode lines will be ignored."
+  :type 'boolean
+  :group 'vimvars)
+(make-variable-buffer-local 'vimvars-enabled)
+
+
+(defcustom vimvars-check-lines 5
+  "The number of lines in the top or bottom of a file that we will search for VIM settings (VIM itself checks 5)."
+  :type 'integer
+  :group 'vimvars)
+
+
+(defcustom vimvars-ignore-mode-line-if-local-variables-exist t
+  "If non-nil, VIM mode lines are ignored in files that have Emacs local variables."
+  :type 'boolean
+  :group 'vimvars)
+
+
+;; It appears that real VIM accepts backslash-escaped characters (for
+;; example \\| inside makeprg).
+;;
+;; Also, VIM accepts vi: and vim: at start-of line (but not ex:)
+;;
+;; Google Code search can be helpful in assessing what options are widely used,
+;; for example see
+;; <http://codesearch.google.com/codesearch?q=(ex|vim%3F):\+(se\+|setlocal)>
+(defconst vimvars-modeline-re
+  "\\(^\\|[ 	]\\)\\(ex\\|vim?\\):[	 ]?\\(set\\|setlocal\\|se\\)? \\([^:]+\\):"
+  "Regex matching a VIM modeline.")
+
+
+(defun vimvars-should-obey-modeline ()
+  "Return non-nil if a VIM modeline should be obeyed in this file."
+  ;; Always return nil if vimvars-enabled is nil.
+  ;; Otherwise, if there are Emacs local variables for this file,
+  ;; return nil unless vimvars-ignore-mode-line-if-local-variables-exist
+  ;; is also nil.
+  (when vimvars-enabled
+    (if file-local-variables-alist
+        (not vimvars-ignore-mode-line-if-local-variables-exist)
+      t)))
+
+  
+(defun vimvars-accept-tag (leader tag)
+  "Return non-nil if LEADER followed by TAG should be accepted as a modeline."
+  (cond
+   ((equal "vim" tag) t)
+   ((equal "vi" tag) t)
+   ;; Accept "ex:" only when it is not at the beginning of a line.
+   ((equal "ex" tag) (not (equal 0 (length leader))))
+   (t nil)))
+
+
+(defun vimvars-obey-this-vim-modeline ()
+  "Obey the mode line in the current regex match string."
+  (message "found a modeline: %s" (match-string 0))
+  (let ((settings-end (match-end 4)))
+    ;; We ignore the local suffix, since for Emacs
+    ;; most settings will be buffer-local anyway.
+    ;;(message "found VIM settings %s" (match-string 4))
+    (goto-char (match-beginning 4))
+    ;; Look for something like this: vi: set sw=4 ts=4:
+    ;; We should look for it in a comment, but for now
+    ;; we won't worry about the syntax of the major mode.
+    (while (re-search-forward
+            " *\\([^= ]+\\)\\(=\\([^ :]+\\)\\)?" settings-end t)
+      (let ((variable (vimvars-expand-option-name (match-string 1))))
+        (if (match-string 3)
+            (vimvars-assign variable (match-string 3))
+          (vimvars-enable-feature variable)))))
+  t)
+
+
+(defun vimvars-obey-top-modeline ()
+  "Check for, and if found, obey a mode line at the top of the file.
+This function moves point."
+  (goto-char (point-min))
+  (if (and
+       (re-search-forward vimvars-modeline-re
+	            (line-end-position vimvars-check-lines) t)
+       (vimvars-accept-tag (match-string 1) (match-string 2)))
+      (vimvars-obey-this-vim-modeline)))
+
+  
+(defun vimvars-obey-bottom-modeline ()
+  "Check for, and if found, obey a mode line at the botom of the file.
+This function moves point."
+  (goto-char (point-max))
+  (if (and
+       (re-search-backward vimvars-modeline-re 
+	             (line-beginning-position 
+		(- 1 vimvars-check-lines)) t)
+       (vimvars-accept-tag (match-string 1) (match-string 2)))
+      (vimvars-obey-this-vim-modeline)))
+  
+
+(defun vimvars-obey-vim-modeline ()
+  "Check the top and bottom of a file for VIM-style settings, and obey them.
+Only the first and last `vimvars-check-lines' lines of the file
+are checked for VIM variables.   You can use this in `find-file-hook'."
+  (when (vimvars-should-obey-modeline)
+    (save-excursion
+      (or (vimvars-obey-top-modeline)
+          (vimvars-obey-bottom-modeline)))))
+
+
+
+(defun vimvars-set-indent (indent)
+  "Set the amount of indentation caused by tab to INDENT in a mode-aware way."
+  (when (equal major-mode 'c-mode) (setq c-basic-offset indent)))
+
+
+(defun vimvars-expand-option-name (option)
+  "Expand the abbreviated VIM :set variable OPTION to its full name."
+  (let ((expansion
+	 (assoc option
+		'(("ro" "readonly")
+		  ("sts" "softtabstop")
+		  ("sw" "shiftwidth")
+		  ("ts" "tabstop")
+		  ("tw" "textwidth")))))
+    (if expansion (cadr expansion) option)))
+   
+
+;;; Not supported:
+;;; comments/com (comment leader), because it's not language-specific in VIM.
+(defun vimvars-assign (var val)
+  "Emulate VIM's :set VAR=VAL."
+  (message "Setting VIM option %s to %s in %s" var val (buffer-name))
+  (cond
+   ((equal var "makeprg") (setq compile-command val))
+   ((equal var "shiftwidth") (vimvars-set-indent (string-to-number val)))
+   ((equal var "softtabstop") t) ; Ignore.
+   ((equal var "tabstop") (setq tab-width (string-to-number val)))
+   ((equal var "textwidth") (set-fill-column (string-to-number val)))
+   (t (message "Don't know how to emulate VIM variable %s" var))))
+
+
+;; FIXME: Also consider supporting ...
+;; fileencoding, encoding could be useful but likely too hairy
+;; fileformat
+;; tags
+;; textmode (but this is obsolete in VIM, replaced by fileformat)
+;; Not supported:
+;; bomb/nobomd (byte order mark control), because I don't expect it is
+;; comonly enough used to justify the maintenance burden.
+(defun vimvars-enable-feature (var)
+  "Emulate VIM's :set VAR for variables that are just boolean."
+  (message "Enabling VIM option %s in %s" var (buffer-name))
+  (cond
+   ((equal var "expandtab") (setq indent-tabs-mode nil))
+   ((equal var "ignorecase") (setq case-fold-search t))
+   ((equal var "readonly") (toggle-read-only 1))
+   ((equal var "wrap") (setq truncate-lines nil))
+   ((equal var "write") (toggle-read-only -1)) ; Similar, not the same.
+   
+   ((equal var "noexpandtab") (setq indent-tabs-mode t))
+   ((equal var "noignorecase") (setq case-fold-search nil))
+   ((equal var "noreadonly") (toggle-read-only -1))
+   ((equal var "nowrap") (setq truncate-lines t))
+   ((equal var "nowrite") (toggle-read-only 1)) ; Similar, not the same
+
+   (t (message "Don't know how to emulate VIM feature %s" var))))
+
+(provide 'vimvars)
+;;; vimvars.el ends here


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

* bug#8754: submission of vimvars
  2011-05-28 22:39 ` bug#8754: submission of vimvars James Youngman
  2011-05-29  8:25   ` Štěpán Němec
  2011-05-29 17:21   ` Nix
@ 2011-06-14 16:11   ` James Youngman
  2011-07-06 13:12   ` Stefan Monnier
  3 siblings, 0 replies; 12+ messages in thread
From: James Youngman @ 2011-06-14 16:11 UTC (permalink / raw)
  To: 8754

Is there any news on the status of this patch?
James.





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

* bug#8754: submission of vimvars
  2011-05-29  8:25   ` Štěpán Němec
@ 2011-06-14 16:27     ` James Youngman
  0 siblings, 0 replies; 12+ messages in thread
From: James Youngman @ 2011-06-14 16:27 UTC (permalink / raw)
  To: Štěpán Němec; +Cc: 8754

On Sun, May 29, 2011 at 09:25, Štěpán Němec <stepnem@gmail.com> wrote:
> P.S.: There was also this package with a similar goal last time I
> looked:
>
>  http://bitbucket.org/danderson/evimodeline
>
> Do you know about that one?

I didn't.   But looking at it, I see it's simpler than vimvars
(meaning, it's much easier to see it's doing the right kind of thing
and generally it's probably easier to maintain) but there are some
respects in which it interacts less nicely with both Emacs and VI than
vimvars:

 - vimvars knows not to apply the vi mode line when a file has Emacs
local variables too (though the user can change this)
 - vimvars checks for a vi modeline at both the bottom and the top of a file
 - vimvars will not regex search through an arbitrarily long file
 - vimvars also supports the vi modeline items makeprg, ignorecase, wrap
 - vimvars supports the "no" prefixes for each relevant option (for
turning things off)
 - vimvars has some support for M-x custom
 - vimvars has slightly closer emulation of vi-related editors'
behaviour with "ex: set" (specifically, it's ignored at BOL).

Slightly less relevant:
 - vimvars has a regression test (not included in the initial
submission because it would need to be modified to fit in with Emacs'
tests and it was only worth doing that if the original submission was
accepted).
 - vimvars has (a small amount of) Texinfo documentation

James.
-- 
Google Ireland Ltd., Gordon House, Barrow Street, Dublin 4, Ireland
Registered in Dublin, Ireland.  Registration Number: 368047
http://tinyurl.com/345mmx





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

* bug#8754: submission of vimvars
  2011-05-28 22:39 ` bug#8754: submission of vimvars James Youngman
                     ` (2 preceding siblings ...)
  2011-06-14 16:11   ` James Youngman
@ 2011-07-06 13:12   ` Stefan Monnier
  2011-07-06 14:22     ` James Youngman
  3 siblings, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2011-07-06 13:12 UTC (permalink / raw)
  To: James Youngman; +Cc: 8754

> Sorry, I'm attaching the patch instead of sending it inline, contrary
> to the contribution guidelines, but I'll include the commit message
> inline.  Google already has an FSF copyright assignment for Emacs;
> fwiw, so do I.   Feedback on the right place in the manual to document
> this would be particularly welcome, since I wasn't certain which the
> optimal spot was.

This looks like an interesting feature, thanks.
I think we should add it to the GNU ELPA, does that sound goo to you?

- There's some redundancy between vimvars-enabled and (memq
  'vimvars-obey-vim-modeline find-file-hook), I think the user should
  only have to use one of the two.
- if vimvars-enabled stays, it should be renamed vimvars-mode and be
  made into a minor-mode.
- vimvars-enabled being buffer-local seems odd.  What was the motivation
  for it?
- if the user has to add vimvars-obey-vim-modeline to the hook, then add
  an autoload cookie before it so that the user does not need to
  (require 'vimvars).
-
    (if file-local-variables-alist
        (not vimvars-ignore-mode-line-if-local-variables-exist)
      t)))
  =>
    (or (not file-local-variables-alist)
        (not vimvars-ignore-mode-line-if-local-variables-exist))
  =>
    (not (and file-local-variables-alist
              vimvars-ignore-mode-line-if-local-variables-exist))
- next time someone adds support for shiftwidth in some other modes
  (e.g. by setting smie-basic-indent), he'll probably forget to update
  the doc, so better keep the doc less specific to the current limits.
- (equal major-mode 'c-mode)  =>  (derived-mode-p 'c-mode).
- you set compile-command globally.
- if we add it to the GNU ELPA rather than to Emacs itself, then the doc
  needs to be moved to the Commentary section.


        Stefan





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

* bug#8754: submission of vimvars
  2011-07-06 13:12   ` Stefan Monnier
@ 2011-07-06 14:22     ` James Youngman
  2011-07-06 16:34       ` Stefan Monnier
  0 siblings, 1 reply; 12+ messages in thread
From: James Youngman @ 2011-07-06 14:22 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 8754

On Wed, Jul 6, 2011 at 14:12, Stefan Monnier <monnier@iro.umontreal.ca> wrote:
>
> > Sorry, I'm attaching the patch instead of sending it inline, contrary
> > to the contribution guidelines, but I'll include the commit message
> > inline.  Google already has an FSF copyright assignment for Emacs;
> > fwiw, so do I.   Feedback on the right place in the manual to document
> > this would be particularly welcome, since I wasn't certain which the
> > optimal spot was.
>
> This looks like an interesting feature, thanks.
> I think we should add it to the GNU ELPA, does that sound goo to you?

I'm not opposed, but it is not my ideal choice for a small number of reasons:
1. It interacts a bit with Emacs' own local variables in order to
avoid surprising behaviour, and my guess was that it may make sense to
put the code in the same repo as the code interpreting Emacs' own
local variables.
2. I wanted to make sure this was adequately documented in the same
place as the Emacs' various VI emulations, since people wanting to use
a VI emulation stand a high chance of finding this useful too.

> - There's some redundancy between vimvars-enabled and (memq
>  'vimvars-obey-vim-modeline find-file-hook), I think the user should
>  only have to use one of the two.

I had to make some assumptions about user preferences, and I guessed
that someone might want to leave vimvars-obey-vim-modeline in
find-file-hook and yet disable vimvars for specific projects via
.dir-locals.el.   But I admit my thinking on this wasn't that
exhaustive.

> - if vimvars-enabled stays, it should be renamed vimvars-mode and be
>  made into a minor-mode.
> - vimvars-enabled being buffer-local seems odd.  What was the motivation
>  for it?
> - if the user has to add vimvars-obey-vim-modeline to the hook, then add
>  an autoload cookie before it so that the user does not need to
>  (require 'vimvars).

[ and some other code style changes, thanks for those, I'll incorporate them. ]


> - next time someone adds support for shiftwidth in some other modes
>  (e.g. by setting smie-basic-indent), he'll probably forget to update
>  the doc, so better keep the doc less specific to the current limits.

Good tip, thanks.

> - (equal major-mode 'c-mode)  =>  (derived-mode-p 'c-mode).
> - you set compile-command globally.

Oops.   Thanks for catching this.  It turns out that makeprg cannot be
set in vi in a modeline anyway (only in .vimrc) so that feature needs
to be removed in any case.   I'm pretty sure this is the only such
case.

> - if we add it to the GNU ELPA rather than to Emacs itself, then the doc
>  needs to be moved to the Commentary section.
>
>
>        Stefan



--
Google Ireland Ltd., Gordon House, Barrow Street, Dublin 4, Ireland
Registered in Dublin, Ireland.  Registration Number: 368047
http://tinyurl.com/345mmx





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

* bug#8754: submission of vimvars
  2011-07-06 14:22     ` James Youngman
@ 2011-07-06 16:34       ` Stefan Monnier
  2011-07-06 16:50         ` James Youngman
  0 siblings, 1 reply; 12+ messages in thread
From: Stefan Monnier @ 2011-07-06 16:34 UTC (permalink / raw)
  To: James Youngman; +Cc: 8754

>> > Sorry, I'm attaching the patch instead of sending it inline, contrary
>> > to the contribution guidelines, but I'll include the commit message
>> > inline.  Google already has an FSF copyright assignment for Emacs;
>> > fwiw, so do I.   Feedback on the right place in the manual to document
>> > this would be particularly welcome, since I wasn't certain which the
>> > optimal spot was.
>> This looks like an interesting feature, thanks.
>> I think we should add it to the GNU ELPA, does that sound goo to you?

> I'm not opposed, but it is not my ideal choice for a small number of reasons:
> 1. It interacts a bit with Emacs' own local variables in order to
> avoid surprising behaviour, and my guess was that it may make sense to
> put the code in the same repo as the code interpreting Emacs' own
> local variables.
> 2. I wanted to make sure this was adequately documented in the same
> place as the Emacs' various VI emulations, since people wanting to use
> a VI emulation stand a high chance of finding this useful too.

The problem is that we entered feature freeze for Emacs-24.1 a week ago,
and I don't think this is high-enough priority to overrule it.  We can
reconsider it for Emacs-24.2 (at which point we may also reconsider the
way it hooks into Emacs: we could probably make it more robust by
hooking into hack-local-variables instead, tho this may currently lack
the necessary hooks).

>> - There's some redundancy between vimvars-enabled and (memq
>>  'vimvars-obey-vim-modeline find-file-hook), I think the user should
>>  only have to use one of the two.

> I had to make some assumptions about user preferences, and I guessed
> that someone might want to leave vimvars-obey-vim-modeline in
> find-file-hook and yet disable vimvars for specific projects via
> .dir-locals.el.

That makes sense (but see below).  Note that as long as vimvars-enabled
is nil (add-hook 'find-file-hook 'vimvars-obey-vim-modeline) is
harmless, so you could arrange to add the hook eagerly (e.g. default
vimvars-enabled to nil and add the hook unconditionally), so the user
only has to deal with vimvars-enabled.

>> - if vimvars-enabled stays, it should be renamed vimvars-mode and be
>>  made into a minor-mode.
>> - vimvars-enabled being buffer-local seems odd.  What was the motivation
>>  for it?

You don't need to call make-variable-buffer-local for dir-locals to work.
make-variable-buffer-local basically says "this will only ever be set
buffer-locally", which is not right, here.  Just remove it and things
will keep working fine.


        Stefan





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

* bug#8754: submission of vimvars
  2011-07-06 16:34       ` Stefan Monnier
@ 2011-07-06 16:50         ` James Youngman
  2012-04-12 19:33           ` Lars Magne Ingebrigtsen
  0 siblings, 1 reply; 12+ messages in thread
From: James Youngman @ 2011-07-06 16:50 UTC (permalink / raw)
  To: Stefan Monnier; +Cc: 8754

Targeting 24.2 seems like a good idea to me, then.   Thanks.   I will
work on your other comments soon.





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

* bug#8754: submission of vimvars
  2011-07-06 16:50         ` James Youngman
@ 2012-04-12 19:33           ` Lars Magne Ingebrigtsen
  2016-02-25  6:57             ` Lars Ingebrigtsen
  0 siblings, 1 reply; 12+ messages in thread
From: Lars Magne Ingebrigtsen @ 2012-04-12 19:33 UTC (permalink / raw)
  To: James Youngman; +Cc: 8754

James Youngman <youngman@google.com> writes:

> Targeting 24.2 seems like a good idea to me, then.   Thanks.   I will
> work on your other comments soon.

The Emacs 24.2 window opened recently, so if you're planning on
respinning this patch, now is probably a good time.

-- 
(domestic pets only, the antidote for overdose, milk.)
  bloggy blog http://lars.ingebrigtsen.no/





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

* bug#8754: submission of vimvars
  2012-04-12 19:33           ` Lars Magne Ingebrigtsen
@ 2016-02-25  6:57             ` Lars Ingebrigtsen
  0 siblings, 0 replies; 12+ messages in thread
From: Lars Ingebrigtsen @ 2016-02-25  6:57 UTC (permalink / raw)
  To: James Youngman; +Cc: 8754, Stefan Monnier

Lars Magne Ingebrigtsen <larsi@gnus.org> writes:

> James Youngman <youngman@google.com> writes:
>
>> Targeting 24.2 seems like a good idea to me, then.   Thanks.   I will
>> work on your other comments soon.
>
> The Emacs 24.2 window opened recently, so if you're planning on
> respinning this patch, now is probably a good time.

That was three years ago, so I would guess that this isn't going to
happen.  I'm closing the bug report; please reopen if needed.

-- 
(domestic pets only, the antidote for overdose, milk.)
   bloggy blog: http://lars.ingebrigtsen.no





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

end of thread, other threads:[~2016-02-25  6:57 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <BANLkTikYHe-dgUUbv1ZW+HNF4AvO9fNB8g@mail.gmail.com>
2011-05-28 22:39 ` bug#8754: submission of vimvars James Youngman
2011-05-29  8:25   ` Štěpán Němec
2011-06-14 16:27     ` James Youngman
2011-05-29 17:21   ` Nix
2011-05-29 18:05     ` James Youngman
2011-06-14 16:11   ` James Youngman
2011-07-06 13:12   ` Stefan Monnier
2011-07-06 14:22     ` James Youngman
2011-07-06 16:34       ` Stefan Monnier
2011-07-06 16:50         ` James Youngman
2012-04-12 19:33           ` Lars Magne Ingebrigtsen
2016-02-25  6:57             ` Lars Ingebrigtsen

Code repositories for project(s) associated with this public inbox

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

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).