From: Colin Walters <walters@gnu.org>
Subject: the overloading of `tab-width'
Date: 15 Jun 2002 13:38:20 -0400 [thread overview]
Message-ID: <1024162700.14414.578.camel@space-ghost> (raw)
[-- Attachment #1: Type: text/plain, Size: 2831 bytes --]
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.
[-- Attachment #2: disptabwidth.patch --]
[-- Type: text/x-patch, Size: 3435 bytes --]
Index: src/buffer.h
===================================================================
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;
/* 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
===================================================================
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);
XSETFASTINT (buffer_defaults.tab_width, 8);
+ buffer_defaults.display_tab_width = Qnil;
buffer_defaults.truncate_lines = Qnil;
buffer_defaults.ctl_arrow = Qt;
buffer_defaults.direction_reversed = 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 @@
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_width,
+ 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. */);
DEFVAR_PER_BUFFER ("ctl-arrow", ¤t_buffer->ctl_arrow, Qnil,
doc: /* *Non-nil means display control chars with uparrow.
next reply other threads:[~2002-06-15 17:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2002-06-15 17:38 Colin Walters [this message]
2002-06-15 18:21 ` the overloading of `tab-width' Colin Walters
2002-06-15 18:57 ` Kai Großjohann
2002-06-16 23:28 ` Richard Stallman
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1024162700.14414.578.camel@space-ghost \
--to=walters@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).