From mboxrd@z Thu Jan 1 00:00:00 1970 Path: main.gmane.org!not-for-mail From: Colin Walters Newsgroups: gmane.emacs.devel Subject: the overloading of `tab-width' Date: 15 Jun 2002 13:38:20 -0400 Sender: emacs-devel-admin@gnu.org Message-ID: <1024162700.14414.578.camel@space-ghost> NNTP-Posting-Host: localhost.gmane.org Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-VjnJ6b8VsqGBfej5U8Cv" X-Trace: main.gmane.org 1024162938 1088 127.0.0.1 (15 Jun 2002 17:42:18 GMT) X-Complaints-To: usenet@main.gmane.org NNTP-Posting-Date: Sat, 15 Jun 2002 17:42:18 +0000 (UTC) Return-path: Original-Received: from quimby.gnus.org ([80.91.224.244]) by main.gmane.org with esmtp (Exim 3.33 #1 (Debian)) id 17JHZ4-0000HR-00 for ; Sat, 15 Jun 2002 19:42:18 +0200 Original-Received: from fencepost.gnu.org ([199.232.76.164]) by quimby.gnus.org with esmtp (Exim 3.12 #1 (Debian)) id 17JHyP-00008d-00 for ; Sat, 15 Jun 2002 20:08:30 +0200 Original-Received: from localhost ([127.0.0.1] helo=fencepost.gnu.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 17JHYu-0002aH-00; Sat, 15 Jun 2002 13:42:08 -0400 Original-Received: from monk.debian.net ([216.185.54.61] helo=monk.verbum.org) by fencepost.gnu.org with esmtp (Exim 3.34 #1 (Debian)) id 17JHXf-0002NC-00 for ; Sat, 15 Jun 2002 13:40:52 -0400 Original-Received: from space-ghost.verbum.private (freedom.cis.ohio-state.edu [164.107.60.183]) (using TLSv1 with cipher EDH-RSA-DES-CBC3-SHA (168/168 bits)) (Client CN "space-ghost.verbum.org", Issuer "monk.verbum.org" (verified OK)) by monk.verbum.org (Postfix (Debian/GNU)) with ESMTP id F192274000BA for ; Sat, 15 Jun 2002 13:40:39 -0400 (EDT) Original-Received: by space-ghost.verbum.private (Postfix (Debian/GNU), from userid 1000) id 840248FC9F1; Sat, 15 Jun 2002 13:38:21 -0400 (EDT) Original-To: emacs-devel@gnu.org X-Mailer: Ximian Evolution 1.0.3 Errors-To: emacs-devel-admin@gnu.org X-BeenThere: emacs-devel@gnu.org X-Mailman-Version: 2.0.9 Precedence: bulk List-Help: List-Post: List-Subscribe: , List-Id: Emacs development discussions. List-Unsubscribe: , List-Archive: Xref: main.gmane.org gmane.emacs.devel:4892 X-Report-Spam: http://spam.gmane.org/gmane.emacs.devel:4892 --=-VjnJ6b8VsqGBfej5U8Cv Content-Type: text/plain Content-Transfer-Encoding: 7bit So, I've been doing a lot of work on another project, whose authors start out every file with: /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ Now, personally, I find this irritating in the extreme. If I nest about four blocks, with a long function name or two, the lines begin to wrap very quickly. One thing I do like about the GNU Coding style is that it says to perform indentation by 2 columns. Unfortunately, believe it or not, Emacs gives me no way to deal with this. You may say, "You can just change `tab-width'", but in fact I can't. If I set `tab-width' to 2, then everything shrinks nicely to the left. However, I can't just hit TAB anymore to do indentation, because CC mode decides it has to insert *four* tabs in order to make up to the `c-basic-offset' value of 8. Now, your next response might be, "Why can't you just set *both* c-basic-offset and tab-width to 2"? And the answer is because that can change the buffer's representation on disk. For example, in the following code: static char * get_file_content (EMsgComposer *composer, const char *file_name, gboolean want_html, guint flags, gboolean warn) { [...] if (fd == -1) { [...] if (warn) { msg = g_strdup_printf (_("Error while reading file %s:\n%s"), file_name, g_strerror (errno)); If I hit TAB on the last line while `c-basic-offset' and `tab-width' are both 8, everything is fine. However, If I set them both to 2, then hit TAB, CC mode will insert a bunch of tab characters to try to line it up with the end of function name, which is wrong. Really, I don't want to change the representation on disk at all. I think this problem came about because packages started using `tab-width' to convert between actual TAB and space characters. According to its docstring, it is only for display purposes, but CC mode and functions like `tabify' use it for other purposes. So I finally got fed up enough with this situation to write the following patch. It should basically be self-explanatory. The final question is probably "What's the disadvantage?". Given that the tab/space problem has plagued programmers for decades, one would have every right to be surprised if this patch could make things Just Work the way each person wants it to. And indeed, there is a disadvantage: If I keep the (awful) settings of `c-basic-offset' and `tab-width' => 8, which I must do in order to prevent spurious conflicts and bloated patches, but I set `display-tab-width' => 2, then in the above situation, the parameters no longer line up with the function name (in display terms). But I'm willing to live with that disadvantage, in order to get much less line wrapping. Another solution we should pursue is giving some way to tell CC mode to *only* insert tabs when performing indentation. --=-VjnJ6b8VsqGBfej5U8Cv Content-Disposition: attachment; filename=disptabwidth.patch Content-Transfer-Encoding: quoted-printable Content-Type: text/x-patch; name=disptabwidth.patch; charset=ISO-8859-1 Index: src/buffer.h =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/emacs/emacs/src/buffer.h,v retrieving revision 1.85 diff -u -d -r1.85 buffer.h --- src/buffer.h 10 Jan 2002 11:13:17 -0000 1.85 +++ src/buffer.h 15 Jun 2002 17:38:29 -0000 @@ -594,10 +594,11 @@ Lisp_Object category_table; =20 /* Values of several buffer-local variables. */ - /* tab-width is buffer-local so that redisplay can find it - in buffers that are not current. */ + /* tab-width and display-tab-width are buffer-local so that + redisplay can find it in buffers that are not current. */ Lisp_Object case_fold_search; Lisp_Object tab_width; + Lisp_Object display_tab_width; Lisp_Object fill_column; Lisp_Object left_margin; /* Function to call when insert space past fill column. */ Index: src/buffer.c =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D RCS file: /cvsroot/emacs/emacs/src/buffer.c,v retrieving revision 1.388 diff -u -d -r1.388 buffer.c --- src/buffer.c 8 Jun 2002 20:25:31 -0000 1.388 +++ src/buffer.c 15 Jun 2002 17:38:30 -0000 @@ -4859,6 +4859,7 @@ XSETFASTINT (buffer_defaults.overlay_center, BEG); =20 XSETFASTINT (buffer_defaults.tab_width, 8); + buffer_defaults.display_tab_width =3D Qnil; buffer_defaults.truncate_lines =3D Qnil; buffer_defaults.ctl_arrow =3D Qt; buffer_defaults.direction_reversed =3D Qnil; @@ -4919,6 +4920,7 @@ XSETFASTINT (buffer_local_flags.selective_display_ellipses, idx); ++idx; #endif XSETFASTINT (buffer_local_flags.tab_width, idx); ++idx; + XSETFASTINT (buffer_local_flags.display_tab_width, idx); ++idx; XSETFASTINT (buffer_local_flags.truncate_lines, idx); ++idx; XSETFASTINT (buffer_local_flags.ctl_arrow, idx); ++idx; XSETFASTINT (buffer_local_flags.fill_column, idx); ++idx; @@ -5288,7 +5290,28 @@ =20 DEFVAR_PER_BUFFER ("tab-width", ¤t_buffer->tab_width, make_number (Lisp_Int), - doc: /* *Distance between tab stops (for display of tab characters)= , in columns. */); + doc: /* *Distance between tab stops, in columns. +Historically, this variable was only meant to represent the number of +columns which compose a tab character for display purposes. However, +a number of packages began to use it for conversion between tab and +space characters (e.g. `tabify'), as well as calculating how many +tab/space characters to insert into a buffer (e.g. CC mode). + +Therefore, the variable `display-tab-width' (which see) was introduced +to allow you to control the display of a tab character, independently +of how many columns (space characters) you wish it to actually occupy +in the buffer. */); + + DEFVAR_PER_BUFFER ("display-tab-width", ¤t_buffer->display_tab_wid= th, + make_number (Lisp_Int), + doc: /* *Distance between tab stops (for display of tab characters)= , in columns. +In addition to an integer, this variable can also be nil, in which +case the value of `tab-width' is used. + +This variable is only meant for controlling how literal tab characters +are displayed to the user; do not use it to convert between tab and +actual space characters or other purposes! Instead, use the variable +`tab-width' for that. */); =20 DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow, Qnil, doc: /* *Non-nil means display control chars with uparrow. --=-VjnJ6b8VsqGBfej5U8Cv--