Prius saves gas money? (follow-up)

Apr. 17th, 2012 | 08:21 am

Toyota makes the Prius -- a popular hybrid car that gets around 50 miles to the gallon (21 km/L, 4.7L/100km). Presumably, these vehicles save you money at the fuel pump. However, their sticker price is seemingly high. One way to check the economic argument is to compare its total cost with a similar but non-hybrid conventional car and see when driving a hybrid starts saving you money. A convenient and fair comparison is the Corolla also made by Toyota.

Almost 5 years ago, Bill McGonigle compared a Prius with a Corolla and found that only after driving 280613 miles (451603 km) will you start saving money. I confirmed his math with some simple Lisp programming. Has this result changed?

Five years later, the price of gas is up to 4 dollars (US) from 3 dollars but the price point for a Prius is higher. You still need to drive 229354 (369109 km) miles before you start saving gas money. That's 60000 miles (96560 km) less than 5 years ago. Here's the arithmetic in the Emacs Lisp programming language.

(let ((gas-price 4.0)         ;; dollars/gallon
      (prius-price 24000.0)   ;; US dollars
      (corolla-price 16130.0) ;; US dollars
      (prius-mileage 48.0)    ;; miles/gallon
      (corolla-mileage 34.0)) ;; miles/gallon
  (/
   (* prius-mileage corolla-mileage
      (/ (- prius-price corolla-price) gas-price))
   (- prius-mileage corolla-mileage)))

Toyota has introduced a new c model of the Prius this year. A smaller-sized version, it is tuned to get better mileage in the city -- better than it does for highway driving. It's also 15% cheaper than the regular Prius. If you compared a city-driving Corolla with the Prius c you'd only have to drive 38802 miles (62446 km). That's pretty good, but is it a fair comparison? Here's that arithmetic before I answer that question.

(let ((gas-price 4.0)         ;; dollars/gallon
      (priusc-price 18950.0)  ;; US dollars
      (corolla-price 16130.0) ;; US dollars
      (priusc-mileage 53.0)   ;; miles/gallon
      (corolla-mileage 27.0)) ;; miles/gallon
  (/
   (* priusc-mileage corolla-mileage
      (/ (- priusc-price corolla-price) gas-price))
   (- priusc-mileage corolla-mileage)))

Average drivers don't earn 15000 miles (24140 km) a year in the city. Most of those miles are at a highway's pace. Further, the smaller Prius c is more comparable to the Toyota Yaris than a Corolla. Comparing the lower sticker price and highway mileage of a Yaris with the Prius c driven on the highway requires driving 264112 miles (425047 km). Here's the arithmetic.

(let ((gas-price 4.0)         ;; dollars/gallon
      (priusc-price 18950.0)  ;; US dollars
      (yaris-price 14115.0)   ;; US dollars
      (priusc-mileage 46.0)   ;; miles/gallon
      (yaris-mileage 38.0))   ;; miles/gallon
  (/
   (* priusc-mileage yaris-mileage
      (/ (- priusc-price yaris-price) gas-price))
   (- priusc-mileage yaris-mileage)))

After 5 years, the hybrid car still isn't economical unless a typical owner drives one for 15 years. According to Consumer Reports, Toyota's reputation for reliability is extending to the Prius, where a Prius is able to maintain its efficiency and the batteries have held up after 10 years. However, the average Prius owner probably doesn't hold on to the car this long.

More likely, consumers purchase hybrid vehicles because of their reduced environmental impact. It's estimated that just producing a car can be 10 to 20% of a vehicle's lifetime emissions. Presumably, the energy to make a Prius is greater than a conventional car since it has two engines (combustion and electrical) and additional battery. However, Toyota doesn't release the estimated emissions from manufacturing a Prius.

The city-optimized Prius c is a triple threat in metropolitan areas for its lower price, better efficiency and reduce impact on smog. However, these places typically have mass transit. The best way to save money is commute by walking, biking, car pooling or taking the bus or train. These options are better for the environment as well.

Link | Leave a comment {15} | Add to Memories | Share

Spring cleaning

Jan. 5th, 2012 | 12:09 pm

After 50 years as an academic economist, spending it deconstructing the neo-classical economics of Alfred Marshall and his "Cambridge School" -- of which she was a member early in her career -- and producing work deserving of a Nobel Prize, Joan Robinson would instead see the system resurrected in the US -- notably by the "Chicago School" of Milton Friedman and Fred Hayek. In 1980, she commented on the poverty of orthodox economics and sketched a solution.

After the Second World War, the baton of leadership in teaching economics, along with leadership in the capitalist world, passed to the USA. Instead of meeting the challenge of the Keynesian revolution head on, the profession in the USA split the subject into two parts, macro and micro. In the macro section it was permissible to contemplate fluctuations in employment and even to hint at remedies for a deficiency in effective demand, while micro theory returned to the analysis of equilibrium established by the free play of market forces. Keynesian ideas were allowed a certain sphere of operation while the central doctrine was safely walled off from them.[...]

The whole subject [of inequality] is so embarrassing that in fact it is scarcely mentioned. There is no treatment at all of the determination of the distribution of income in orthodox teaching, and precious little about its consequences. What to the general public appears one of the most interesting of all questions in economics is simply left out of the syllabus.

In its general influence on educated public opinion, orthodox teaching has been not merely feeble and confused but positively pernicious. It gives support to the view that expenditure by a government that is beneficial to the inhabitants of its territory is 'socialism' and must be prevented at all costs. This reconciles an otherwise more or less sane and benevolent public opinion to the arms race which seems to be dragging us all to destruction. But that is another story.

It seems to me that the whole complex of theories and models in the textbooks is in need of a thorough spring cleaning. We should throw out all self-contradictory propositions, unmeasurable quantities and indefinable concepts and reconstruct a logical basis for analysis with what, if anything, remains.

From the essay "The theory of normal prices and reconstruction of economic theory" published in Issues in contemporary macroeconomics and distribution edited by George R. Feiwel.

Tags:

Link | Leave a comment | Add to Memories | Share

Emacs custom global key bindings

Dec. 13th, 2011 | 12:20 pm

The only place reserved for users to put custom global key bindings in Emacs is `C-c LETTER'. (Obviously, all Emacs key bindings can be changed at ones own peril and people often do.) Here's some examples.

(global-set-key (kbd "C-c r") 'query-replace-regexp)
(global-set-key (kbd "C-c i") 'insert-buffer)
(global-set-key (kbd "C-c w") 'write-region)

I also used to like having short aliases for `M-x'. Here's some popular ones used for working with Emacs Lisp.

(defalias 'tdoe 'toggle-debug-on-error)
(defalias 'eval- 'eval-region) ;; M-x eval
(defalias 'load- 'load-file) ;; M-x load
(defalias 'ff 'find-function)
(defalias 'fv 'find-variable)
(defalias 'fl 'find-library)
(defalias 'll 'load-library)

I've come across the strategy of using `C-c' and short words or phrases for key bindings rather than single keys.

(global-set-key (kbd "C-c now")
                (lambda ()
                  "Insert current universal time."
                  (interactive "*")
                  (insert
                   (format-time-string "%Y-%m-%d %H:%M UTC"
                                       (current-time) 'universal))))

(global-set-key (kbd "C-c file") 
                (lambda (file &optional args)
                  "Insert name of FILE into buffer after point."
                  (interactive "*fInsert file name: \nP")
                  (cond ((eq '- args)
                         (insert (file-relative-name file)))
                        ((not (null args))
                         (insert (expand-file-name file)))
                        (t
                         (insert file)))))

(global-set-key (kbd "C-c fill") 'fill-region)
(global-set-key (kbd "C-c delete") 'delete-region)
(global-set-key (kbd "C-c svn") 'svn-status)
(global-set-key (kbd "C-c git") 'magit-status)
(global-set-key (kbd "C-c compile") 'compile)
;; Same as M-x recompile
(global-set-key (kbd "C-c recompile") 'recompile) 

(global-set-key (kbd "C-c copy SPC line") ;; Repeat with `C-x z'
                (lambda ()
                  (interactive)
                  (forward-line 1)
                  (open-line 1)
                  (copy-from-above-command))) ;; From misc.el
;; Same as M-x copy above RET
(global-set-key "\C-ccopy above" 'copy-from-above-command)

For the seeing Emacs user, display the keys you've pressed earlier by modifying this variable to something closer to the speed of the human eye. By default, Emacs only shows the keys you've entered in the echo area after every one second.

(setq echo-keystrokes 0.02)

It's nice how Emacs automatically creates prefix key maps for these long key sequences. For instance, `C-c compile' and `C-c copy line' share the `C-c c' and `C-c co' prefixes. However, there is no way to use both single key bindings and the new longer ones simultaneously should they share letters. When they conflict, the shorter will get stomped by the longer version. For example, the previous single key binding for `C-c r' will not work since it gets shadowed by `C-c recompile'.

I'm using a mix of both short and long key bindings since there are some editing commands that I need to keep on a short key binding but some less frequently used commands on single key bindings that I couldn't remember easily. Although, it is a delicate dance of picking useful short phrases that don't conflict with single key bindings and vice versa. I'm not planning to get carried away with it all. I'm a satisfied user of M-x.

Link | Leave a comment | Add to Memories | Share

World War Two Veteran Quote

Nov. 11th, 2011 | 11:50 am

I don’t think there’s ever been a good war, never been one. It’s the height of ignorance. I mean, it’s legalized murder. You’re killing somebody and then your mother teaches you to believe in God and then, at 17, they say now we’re gonna show you how to kill. It’s too schizophrenic. It doesn’t make sense. We should believe in God, believe in being a human being, and giving to the earth instead of taking from it. -- Anthony Dominick Benedetto

Tony Bennett recently received criticism for making the obvious point about a so-called war on terrorism, "But who are the terrorists? Are we the terrorists or are they the terrorists? Two wrongs don’t make a right."

Tony Bennett served in the the US Army and a tour in the final year of the second World War that began in France and ended in Germany. He saw the Battle of the Bulge, spent winter months in a foxhole, engaged in town-to-town fighting and liberated one of the German concentration camps at Dachau.

It's said that freedoms in the US were and are fought for in wars here and abroad. If you fight in a war don't you get the right to speak freely? It was a corollary that never existed. It was invented.

Studies have shown that recent veterans are facing unemployment at twice the US average. Returning veterans represent nearly 1/5 of all suicides. More recently, Dover Air Force Base has been found to be mishandling the remains of soldiers returning from US occupations and interventions.

I do not participate in the genuflection and formal observance of Veteran's Day, but will support the rights and respect of veterans every day of the year.

Link | Leave a comment | Add to Memories | Share

Update to big Emacs reference card

Aug. 10th, 2011 | 09:58 am

For the first time in over 2 years, I finally got around to updating my giant Emacs reference card. There are now more than 1500 commands up from 1000. It should also be consistent with the latest version of Emacs.

I transform the Wiki markup from a simple text markup using some "quick and dirty" Emacs Lisp. Besides being easier to work on than Wiki markup, the source format is also printable. The HTML version is almost 60 pages. Using a2ps on the text format it prints on 15 pieces of paper.

It's a lot of work, but it's a good way for me to learn more about Emacs. Hopefully, others will find it useful, too. I suggest printing only a few sections that you would like to improve on.

Since it is released under a bunch of free licenses, including version 2 or later of the GNU GPL and version 1.2 or later of the GNU FDL, people are free to share and modify it.
Tags:

Link | Leave a comment | Add to Memories | Share

Learning Emacs key bindings

Jul. 13th, 2011 | 03:14 pm

Emacs key bindings are intimidating at first since they are quite distinct from those used in other applications and platforms. The following is based on discussion on the Emacs IRC channel and is posted to the Emacs Wiki.

After studying the tutorial that comes with Emacs, most people learn best by doing and not just by reading over a list of commands and trying to memorize them. Get yourself a text file to play around with. Make a backup copy if you're nervous about losing it. But don't worry -- Emacs makes it hard to lose your work, and it has a great undo command: `C-/' or `C-_'.

Keep the following advice in mind.

  1. Try to memorize the most commonly used commands in the tutorial.
  2. Use Apropos or help to find commands to accomplish a task.
  3. Run the command for a task with `M-x' and typing it in.
  4. Run the command again by using `M-x M-p' or by typing it in again.
  5. On the third time, see if the command is bound to a key binding with `C-h w'.
  6. If you forget a key binding (sometimes you forget even the basic commands introduced in the tutorial), try `C-h w M-p' to peek at it again or use `C-h b' to browse the available bindings.
  7. If you can't burn a key binding in to your brain with this approach, then you're not using it enough and it doesn't deserve a key binding.
  8. If a key binding is atrocious, only then bind the command to an unused key.

Some beginners rush too quickly and add or change key bindings. This avoids learning Emacs and risks spending more time configuring. Competency with `M-x' and help are actually core Emacs skills for life. `M-x' should become your command line in Emacs.

Link | Leave a comment | Add to Memories | Share

Executive Director, GNOME Foundation

Jun. 21st, 2011 | 02:05 pm

It was announced today that Karen Sandler was named new Executive Director of the GNOME Foundation. I don't know Karen, nor am I currently a stock holder of Karen Sandler or the GNOME foundation, but she is a co-host of the Free as in Freedom oggcast of which I'm a dedicated listener.

Given her years as general counsel at the Software Freedom Law Center (SFLC) and the usual legal experience appointing a lawyer to a board gives, Karen is also a good appointment for her non-law insights on free software development by building organizations that sustain and protect the free software ecosystem.

Link | Leave a comment | Add to Memories | Share

The relationship between CentOS and Red Hat

Jun. 8th, 2011 | 01:35 pm

Karanbir Singh (KS) of CentOS was interviewed last November 2010 by Randal Schwartz (RS) and Dan Lynch (DL) on the "FLOSS Weekly" radio program. Here was an interesting portion of the interview.

RS: Give us the top-level view of what CentOS is all about?

KS: So, it's quite a long story, but in a short one-minute setup what happened was that a few years back, Red Hat decided to change their enterprise Linux strategy, and they brought in a subscription model for the product they were going to support. What they also did was left the sources for that product available to the public should anybody want to use it.

What CentOS does is we take those sources and build the distribution with those sources to be as close to the Red Hat offering as possible -- as binary compatible, as ABI-compliant, as API-compliant -- with the only difference being things look different because they have branding in it and you don't get any support. [...]

DL: Is it a good working relationship that you have with Red Hat?

KB: That's a good question. The perspective varies depending on who you speak to. From our end at CentOS, we think we have a very good relationship with Red Hat in that we don't actually have a direct relationship with Red Hat. The components that we are consuming and that Red Hat are putting out they are making available to anybody and everybody, so it could be CentOS it could be Joe Blow.

From the Red Hat side of things, it gets slightly more interesting -- this is of course my personal opinion, not Red Hat opinion -- I feel that Red Hat engineering and Red Hat technical are quite happy with what we're doing because it's not really a one-way street. We take the sources and build a distribution around it, build a platform around it, but what we also do is we file a lot of feature requests, we file patches, we file bug reports. We work with some of their engineering teams to try and solve problems that users are having out in the open. We feel they are happy with us. If you shift the focus a bit and look at Red Hat sales and marketing they're not really that happy with what's happening with CentOS. The one message I try to get across to them is that if there are X number of users using CentOS, then there are X users using the Red Hat platform. [...]

There's some concern that CentOS 6 isn't released even though RHEL 6 has been available for a year, so there must be a crisis or viability issue with CentOS. However, I imagine that a major release of RHEL is non-trivial. If folks want a sooner version of CentOS 6, then there should be resources provided to make that happen. Or buy a support subscription of RHEL 6 from Red Hat. I hear its compatible with the unreleased CentOS 6.

CentOS is important because it is an affordable commercially-developed GNU/Linux distribution. Its also important because it is material proof for the free software community that a commercially-developed GNU/Linux distribution, Red Hat in this case, can be built from source independently by another organization -- commercial or community. CentOS deserves thanks for that as well.

Link | Leave a comment {5} | Add to Memories | Share

Refusing to learn

Feb. 21st, 2011 | 02:11 am

An essay called The psychology of learning from 2003 by Robert Strandh, director of the Département d'Informatique at Université Bordeaux, France, describes a trend in computing where close-mindedness (my phrase) risks opportunities for learning and effectiveness.

The bad-mouthing of competing technologies by adherents of another technology is well known.  The practice goes back to early days of hacker culture when arguments would abound in choice of programming languages (or assembly), mainframe manufacturer or model (consider also "PC versus Mac" over the last two recent decades).  These divisions can partition customers, industries and educators into islands with different customs and ideas.  Strandh doesn't visit this in the essay.  No, according to Strandh, opinions like these arise in young students in more subtle but still worrisome ways.
[...] I have often observed that students are very inefficient in their work. They frequently use methods of working that are unproductive and slow. Some examples:
  • Students do not know how to touch-type. Instead of taking the relatively limited time to learn to do it, they waste many hours per week on slow typing and typing errors.
  • Students frequently do not know how to use advanced features in the text editor such as the interface to the version-control system, the interface to the Lisp system, etc. Again instead of taking a short time to learn, they waste much more time.
  • Students do not know how to use a debugger. Instead, they waste time debugging programs with trace output. [...]
Strandh suggests this could simply be "reluctance to learning new tools and methods", but can also become "a kind of reaction orders of magnitude stronger". He attributes the reaction to "a need to achieve performance immediately" (original emphasis). Continuing:
Such performance leaves no time for intellectual curiosity. Instead, techniques already known to them must be applied to solve problems. To these people, failure is a disaster whose sole feature is to harm instant performance. Similarly, learning represents the possibility of failure and must thus be avoided if possible. To the people in this category, knowledge in other people also represents a threat. As long as everybody around them use tools, techniques, and methods that they themselves know, they can count on outperforming these other people. But when the people around them start learning different, perhaps better, ways, they must defend themselves. [...]
Strandh attributes these behaviors to a description given to him personally by Boston College psychology professor, Lisa Feldman Barrett, who in turn cites the work of well-known psychologist Carol Dweck. The research which posits a duality of perfection-oriented and performance-oriented is worth looking into as an explanation.

The best part of the essay are not about the psychology theory, but his personal anecdotes on computing inspired by the psychology researcher's works.
[...] I talked to a student of computer science who told me why a particular programming language was bad. In fact he told me it was so bad that he had moved to a different university in order to avoid courses that used that particular language. When asked, he admitted he had never written a single program in that language. He simply did not know what he was talking about. And he was willing to fight for it. [...]

[...] I have seen professors in mathematics who were obviously perfection-oriented with respect to mathematics, be firmly in the performance-oriented category with respect to the efficient use of (say) word processors. It is almost a surrealistic experience to see a person in one situation full of intellectual curiosity and wanting to know everything about everything, and in another situation argue why you should not use a particular method that he himself does not know anything about, for reasons that are obviously totally artificial. [...]

[...] I have observed that people ignorant in a particular domain, or not knowing a particular tool or technique, would go to great trouble to explain why knowing this domain, tool, or technique, would be a complete waste of time. Usually these explanations were based on erroneous ideas of what it represented. To make things worse, they were perfectly willing to present their erroneous arguments to the very experts in the field in question. [...]
In this anecode, Strandh likely admits his membership in the Church of Emacs.
[...] I have heard people argue against a tool that they ignore based on the fact that it can do too much. Too much functionality in a tools is a problem only if unneeded or unwanted functionality somehow makes it harder to use the needed and wanted parts. I have heard people argue about the amount of memory a particular tool requires, whereas the additional memory required might represent a cost equivalent to a few hours of work at most. A favorite idea is to label a particular tool with a name suggesting what it ought to be doing, and then arguing that it is doing more than that. For instance, a text editor that is capable of automatic indentation would be accused of being a "kitchen-sink" tool because after all it does much more than allowing the user to just edit text. (original emphasis) [...]
Strandh ends by revealing his own transgressions of this same type.
[...] I myself recently discovered a marvelous feature in a programming language that I had purposely avoided for the past 10 years, simply because 10 years ago, a colleague (who did not know the feature) explained to me that it was no good. We were both victims of our own minds. My colleague because he obviously needed to defend that he had made a different choice, and myself because I subconsciously found it very appealing to be able to brush off the feature as useless and thus not having to learn it. It is hard to overestimate the wasted time I have put in during the past 10 years due to considerably lower productivity than I could have had, had I realized at the time what I now know about human psychology. [...]
I would add another possible explanation for these reactions is another one rooted in "human psychology":  It is a defense mechanism.  Computing possesses a great diversity and many ways to do things.  Barring a few mighty monopolies in hardware and software, there still exists much complexity and specialization in the field of computing.  As regressive overt opinions are, the instinct may be a method for people to manage and focus on their work.  This would especially be the case for budding students.  Avoiding potentially labor-saving tools and knowledge in the rush to finish a task is unfortunate, but investigating alternatives has to be limited or else a task is never started.  It's like the lumberjack (or jill) in the metaphor who sharpens their saw or axe but never cut the tree down since they never got around to swinging the axe.

Despite my sympathy, people who let this close-minded instinct take over and influence themselves and others is indefensible.  People should simply answer "I don't know" rather than than making "complete fools of themselves" by expressing what are only hunches.  A couple famous quotes about "ignorance" and "fear" are probably worth inserting here.  I'll leave it as an exercise.  The point is stop being cavalier and just admit you don't know rather than trying to prove knowing everything.

Link | Leave a comment {3} | Add to Memories | Share

Extending M-x in Emacs

Apr. 27th, 2010 | 11:26 pm

Over 6 months ago, I revealed an Emacs Lisp version of `M-x'. I was pleased to have a few Emacs users who greeted a Lisp replacement for this core primitive with excitement.

What's the benefit of having a Lisp version? Well, it's easier to change than the C version. The syntax is easier and there is no compilation step.

Here's a modification I made to the original. It's a small change, but makes for a good example. It introduces a different representation of the prefix argument in the Minibuffer.

Typically, hitting `C-u' before `M-x' will show "C-u M-x" in the Minibuffer. However, if you issue more than one `C-u', then it just becomes a numeric argument and becomes "16 M-x", "64 M-x", "256 M-x" and so on. The small patch inserted below will show "C-u C-u M-x", "C-u C-u C-u M-x", "C-u C-u C-u C-u M-x" and so on, respectively. There's a good argument for the original behavior, since the powers of 4 are not that memorable to everyone. Letting Emacs handle the arithmetic and show it is helpful. However, visual feedback for what you're typing is a good interface design rule as well. As you can tell I'm agnostic, but like how this small change only takes a small bit of change to the code.

--- m-x.el	2009/08/25 00:03:17	1.1
+++ m-x.el	2009/08/25 00:07:12	1.1.1.1
@@ -22,8 +22,11 @@
 	       (cond ((eq prefixarg '-)
 		      "- ")
 		     ((and (consp prefixarg)
-			   (= (car prefixarg) 4))
-		      "C-u ")
+			   (zerop (% (car prefixarg) 4)))
+		      (apply 'concat
+			     (make-list (truncate
+					 (log (car prefixarg) 4))
+					"C-u ")))
 		     ((and (consp prefixarg)
 			   (integerp (car prefixarg)))
 		      (format "%d " (car prefixarg)))

Emacs knows the difference between a prefix argument with `C-u' and a numeric argument with `M-4' or `C-4'. So, `M-1 M-6 M-x' does not show "C-u C-u M-x" in the Minibuffer.

Here's the complete version of the code.

;; Based on Fexecute_extended_command in keyboard.c of Emacs.
;; Aaron S. Hawley <aaron.s.hawley(at)gmail.com> 2009-08-24
(defun execute-extended-command (prefixarg)
  "Read function name, then read its arguments and call it.

To pass a numeric argument to the command you are invoking with, specify
the numeric argument to this command.

Noninteractively, the argument PREFIXARG is the prefix argument to
give to the command you invoke, if it asks for an argument."
  (interactive "P")
  ;; The call to completing-read wil start and cancel the hourglass,
  ;; but if the hourglass was already scheduled, this means that no
  ;; hourglass will be shown for the actual M-x command itself.
  ;; So we restart it if it is already scheduled.  Note that checking
  ;; hourglass_shown_p is not enough,  normally the hourglass is not shown,
  ;; just scheduled to be shown.
  (let* ((hstarted (and (symbolp window-system)
                        (eq void-text-area-pointer 'hourglass)))
         (saved-keys (this-command-keys-vector)) ;; ?\M-x
         (buf (concat 
               (cond ((eq prefixarg '-)
                      "- ")
                     ((and (consp prefixarg)
                           (zerop (% (car prefixarg) 4)))
                      (apply 'concat
                             (make-list (truncate
                                         (log (car prefixarg) 4))
                                        "C-u ")))
                     ((and (consp prefixarg)
                           (integerp (car prefixarg)))
                      (format "%d " (car prefixarg)))
                     ((integerp prefixarg)
                      (format "%d " prefixarg))
                     (t ""))
               "M-x "))
         (function (completing-read buf obarray 'commandp t nil
                                    'extended-command-history)))
    (if hstarted (setq void-text-area-pointer 'hourglass))
    (if (and (stringp function)
             (= (length function) 0))
        (error "No command name given")
      ;; Set this_command_keys to the concatenation of saved-keys and
      ;; function, followed by a RET.
      (setq saved-keys (vconcat saved-keys
                                function
                                [return]))
      (setq function (intern function)))
    (setq prefix-arg prefixarg)
    (setq this-command function)
    (command-execute function 'record saved-keys)
    ;; If enabled, show which key runs this command.
    (if (and (not (null suggest-key-bindings))
             (null executing-kbd-macro))
        ;; If the command has a key binding, print it now.
        (let ((bindings (where-is-internal function
                                           overriding-local-map t))
              (waited))
          ;; But first wait, and skip the message if there is input.
          (when (and (not (null bindings))
                     (not (and (vectorp bindings)
                               (eq (aref bindings 0)
                                   'mouse-movement))))
              ;; If this command displayed something in the echo area;
              ;; wait a few seconds, then display our suggestion message.
              (if (null (current-message))
                  (setq waited (sit-for 0))
                (if (numberp suggest-key-bindings)
                    (setq waited (sit-for suggest-key-bindings))
                  (setq waited (sit-for 2))))
              (when (and (not (null waited))
                         (not (consp unread-command-events)))
                (with-temp-message (current-message)
                  (let ((binding (key-description bindings)))
                    (message "You can run the command `%s' with %s"
                             function binding)
                    (if (numberp suggest-key-bindings)
                        (setq waited (sit-for suggest-key-bindings))
                      (setq waited (sit-for 2)))))))))))

(provide 'm-x)

Consider putting the above in a file called m-x.el, then put the file in you load-path and add the following to your .emacs file.

(load "m-x")

In the next installment, I will show how to change `M-x' so that it notices a function name at point and offers it as the default command.

Link | Leave a comment {2} | Add to Memories | Share