Showing posts with label emacs. Show all posts
Showing posts with label emacs. Show all posts

Sunday, December 28, 2014

Emacs, flycheck and jshint and other jslinters

One of the benefits to emacs 24 is the new flycheck package.

Once you've installed flycheck be sure to head over to M-x flycheck-info, which should throw up the info manual for flycheck where you can learn that flycheck is the new flymake and how you can extend it. The author(s) of this document aren't shy in expressing their opinion:

"...we consider Flycheck superior to Flymake in all aspects"

I'm no judge of this. I only know that it works well for the things I need it on: js and jshint and also other languages such as php. I won't go into php here, but flycheck will happily use both phpcs - the code sniffer - and phpmd, the mess detector.

I'm probably nowhere near close to using the full capabilities of flycheck. Below I look at chaining an additional linter after jshint to provide indentation warnings.

But before I go any further...

Installing / Setup

I installed flycheck using the emacs package manager (ELPA) and specifically with a the melpa.milkbox.net repository.

Note I have the following in one of my emacs initialisation files (rightly or wrongly) which gives me several package repositories to choose from:

(require 'package)
(add-to-list 'package-archives
             '("marmalade" . "http://marmalade-repo.org/packages/") t)
(add-to-list 'package-archives
             '("melpa-stable" . "http://melpa-stable.milkbox.net/packages/") t)
(add-to-list 'package-archives
             '("melpa" . "http://melpa.milkbox.net/packages/") t)
(package-initialize)

I'm using:

  • flycheck 20141102.652 (use M-x package-list-packages to list and install packages)
    • WARNING: version 20141224.16 is more recent but blows up with my version of gjslint
    • delete it from *Packages* buffer (D) to reinstate the previous version

In my emacs configuration I have this to have flycheck always on:

(global-flycheck-mode 1)

Also, I use helm which means I can run interactive functions using M-x almost and sometimes faster than hitting keyboard shortcuts. It's gotten to the point that I often don't bother trying to add a keyboard shortcut for a new piece of functionality I'm using, preferring instead to hit M-x (helm-M-x under the covers) and typing a few short key strokes to precisely identify the command I want to use.

helm is a revelation, if you haven't tried it, you should.

The vexing issue of javascript major modes in emacs

Yes... it seems we have at least 3:

  • js-mode / javascript-mode
    • this is the in-built js package in emacs
  • js2-mode
    • version 20141224.347 melpa.milkbox.net
  • js3-mode
    • version 20140805.1529 melpa.milkbox.net
  • (There's also a json-mode which is worth installing as well to assist with things like ensuring double quotes.)

I sometimes switch between these.

  • One thing to note is that js2-mode insists on semi-colons, at least by default, and will apply an angry red underline to any offending line that doesn't.
    • This can be turned off with M-x customize-option RET js2-strict-missing-semi-waring and then toggling it off.
  • js3-mode appears to have been modelled on js2-mode and js-mode but tries to support npm-style js conventions which means out of the box it won't worry about semicolons.

Both js2-mode and js3-mode offer some error / linting / parsing and make this available via emacs' next-error facility.

  • In a js file, hitting M-g M-n will invoke next-error which will move you to the next error / warning or issue in your file.
  • M-g M-p will take you to the previous one
  • (Seasoned emacs users may be familiar with these keys since they are used by facilities such as M-x occur (file grepping) and M-x find-grep allowing you to traverse through a list of search hits.)
  • js2-mode will flag standard nodejs globals like require and process as undeclared, whereas js3-mode doesn't.
  • Also, js2-mode doesn't seem to detect some obvious syntax errors such as a double dot "..".

All of this however is unnecessary if you're using flycheck as flycheck will override the next-error system for its own purposes.

I tend to go with js2-mode as it seems more solid with things like switch-statement indentation.

Linters and hinters and code styler sniffers ...

M-x customize-group RET flycheck-executables will give you a good idea of what tools flycheck can handle. For js, there is jshint, gjslint, eslint and also jsonlint (for json).

A bunch of these come from the node eco-system:

sudo npm install -g jshint   # /usr/bin/jshint
sudo npm install -g jsonlint # /usr/bin/jsonlint
sudo npm install -g eslint   # /usr/bin/eslint

For google closure js linter (this is on an archlinux system) I had to do:

sudo easy_install-2.7 http://closure-linter.googlecode.com/files/closure_linter-latest.tar.gz
# /usr/bin/gjslint

Looking up eslint led to some interesting links: jshint and jslint apparently have their own parsers as opposed to using esprima or some other toolkit. eslint has now gone the same way and has its own parser called espree.

My version of flycheck didn't have out-of-the-box support for jscs -- the javascript code style(r) / ?sniffer. But it's not too hard to get it working with flycheck and it also solves the indent problem :) (see further down).

sudo npm install -g jscs     # /usr/bin/jscs

Flycheck and linter configurations

M-x customize-group RET flycheck-config-files allows you to set configuration files for your linters.

You can explicitly set config files for you linters eg you can set:

  • Flycheck Jshintrc: ".jshintrc"
  • Flycheck Gjslintrc: ".gjslintrc"
  • Flycheck Ejslintrc: ".eslintrc"

Flycheck will probably default to looking for dot files of the above form for jshint and gjslint. And it will probably intelligently determine where to look for these dot files in your project.

Using flycheck

Flycheck appears to use jshint by default (assuming you installed it), probably because it is listed before any of the other eligible checkers in flycheck-checkers variable.

In a js file, you should be able to do M-g M-n and M-g M-p to move forwards and backwards over warnings and errors that have been detected (using the next-error interface provided by emacs).

C-c ! l (M-x flycheck-list-errors) will list the errors in a buffer called *Flycheck errors* next to your js file giving you a point and click index into all your linting issues.

I use M-x flycheck-mode to toggle flycheck on and off.

Invoking multiple js linters in flycheck

Use M-x flycheck-select-checker to select a different checker (hint: you should be using helm or something like it which greatly accelerates selections and use of M-x).

  • M-x flycheck-select-checker RET javascript-jshint
  • M-x flycheck-select-checker RET javascript-gjslint
  • M-x flycheck-select-checker RET javascript-eslint

Flycheck has a mechanism for running multiple checkers at the same time which it refers to as chaining. For instance, by default flycheck's php facility will chain mess detector and code sniffer checkers so you will see output from both in the *Flycheck errors* buffer. But for js, by default, flycheck only uses one of supported linters at a time.

Checkers in flycheck are defined using flycheck-define-checker. Chaining checkers requires adding the :next-checkers property to this definition. All the standard in-built checkers are located in elpa/flycheck-20141102.652/flycheck.el .

Here's the jshint checker (it doesn't have :next-checkers property by default):

(flycheck-define-checker javascript-jshint
  "A JavaScript syntax and style checker using jshint.

See URL `http://www.jshint.com'."
  :command ("jshint" "--checkstyle-reporter"
            (config-file "--config" flycheck-jshintrc)
            source)
  :error-parser flycheck-parse-checkstyle
  :error-filter flycheck-dequalify-error-ids
  :modes (js-mode js2-mode js3-mode))

Chaining additional checkers is a topic of interest because, well, indentation...

The equally vexed issue of indenting in javascript

jshint no longer explicitly warns for indentation via the indent option. Boo, sad-face.

Indenting warnings with gjslint...

gjslint may come to the rescue here, it does show warnings for indentation, but it's not clear to me at this point how to control its indentation facility. It looks to be hard-coded to 2 spaces and it has particular ideas about breaking up lines of code that fall under the same rule (0006).

Here's an example of default gjslint preferences on indentation of function parameters :

// BAD: and anything less
promise.then (
  function promiseOk (result) {
  ...

// BAD: Up to this point...
promise.then (
             function promiseOk (result) {
             ...

// OK: if param comes after opening paren...
promise.then (
              function promiseOk (result) {
              ...

Personally I don't have a problem with the first form above, I think it makes the code more readable when a function has complex and extended arguments and reduces chance of exceeding line length.

You can put your gjslint flags passed to the linter on the cli into a flagfile eg create .gjslintrc in the root of your project with the following content:

--jslint_error=indentation

and then invoke like this:

gjslint --flagfile=path/to/.gjslintrc <file>

Flycheck presumably sets the flagfile option if it finds .gjslintrc (assuming you've configured the flycheck-config-files variable (above)). So you can have a .gjslintrc in the root of your project and flycheck will use this for all files.

gjslint lists a rule number or id for each rule that has been infringed. This provides another way to suppress some warnings provided by this linter (if you're using jshint). You can add to your flagfile like this:

--jslint_error=indentation
--disable=0001,0002,0220,0110

The above disabled rules are extra space (0001), missing space (0002), and "no docs found" (0220), line length (0110).

We can get gjslint to chain after jshint by using flycheck-add-next-checker.

In an emacs configuration file:

(with-eval-after-load 'flycheck
  ;; Chain javascript-jscs to run after javascript-jshint.
  (flycheck-add-next-checker 'javascript-jshint '(t . javascript-gjslint)))

This bit of elisp code waits for flycheck to get loaded and then executes its body. It calls flycheck-add-next-checker to add javascript-gjslint as the next checker after javascript-jshint. This means that both will be run on your js file and errors will be organised by line number in the *Flycheck errors* buffer.

Indentation warnings with eslint?

I ran out of gas here. It looks like eslint has taken the same stance as jshint. You can add it all the same using the above with-eval-after-load trick we just did above - but this is not something I'm doing atm.

(with-eval-after-load 'flycheck
  (flycheck-add-next-checker 'javascript-jshint '(t . javascript-eslint)))

Indentation warnings with jscs ... finally!

There doesn't look to be an in-built checker for jscs . This is something that should probably go into flycheck but there's nothing stopping us from using it with flycheck right now.

First, define a flycheck checker in your emacs configuration file(s) somewhere:

(flycheck-define-checker javascript-jscs
  "A JavaScript style checker using jscs.

See URL `https://www.npmjs.com/package/jscs'."
  :command ("jscs" "--reporter=checkstyle" 
            (config-file "--config" flycheck-jscsrc)
            source)
  :error-parser flycheck-parse-checkstyle
  :modes (js-mode js2-mode js3-mode))

For it to work, we'll need to add a file config for it as well:

(flycheck-def-config-file-var flycheck-jscsrc javascript-jscs ".jscsrc"
  :safe #'stringp)

Then add a .jscsrc file to the root of your project. eg

{
    "preset": "google",
    "requireCurlyBraces": null
}

At this point, you can do M-x flycheck-select-checker and see if you can select javascript-jscs. C-c ! l should give you a list of issues (assuming your file has issues).

With the above, I now can get indentation warnings eg if a line is not indented to 2 spaces (using the google preset here) - hooray!

So maybe what we want to do now, apart from tweaking configurations and presets, is combine this with jshint .

Easy enough, we extend what we did before with gjslint but replace it with jscs:


    (with-eval-after-load 'flycheck
    
      ;; Define a checker for jscs...
    
      (flycheck-define-checker javascript-jscs
        "A JavaScript style checker using jscs.
    
      See URL `https://www.npmjs.com/package/jscs'."
        :command ("jscs" "--reporter=checkstyle" 
                  (config-file "--config" flycheck-jscsrc)
                  source)
        :error-parser flycheck-parse-checkstyle
        :modes (js-mode js2-mode js3-mode))
    
      ;; Make flycheck-jscsrc configuration with default.
    
      (flycheck-def-config-file-var flycheck-jscsrc javascript-jscs ".jscsrc"
        :safe #'stringp)
    
      ;; Make javascript-jscs automatically selectable to flycheck
      ;;
      ;; Use t to append at the end so it's not used by default.
    
      (add-to-list 'flycheck-checkers 'javascript-jscs t)
    
      ;; Chain javascript-jscs to run after javascript-jshint.
    
      (flycheck-add-next-checker 'javascript-jshint '(t . javascript-jscs)))

Note we use add-to-list to add our new checker to flycheck-checkers to make it automatically selectable by flycheck, chaining may not work without this. And we take advantage of jscs's checkstyle output which flycheck can already handle.

Tweaking faces for flycheck

Probably because of my theme setup in emacs, the highlighted row in *Flycheck errors* buffer is all grey with the text hidden, so I do

M-x customize-group RET flycheck-faces

and customize Flycheck Error List Highlight and turn inherit off and set background to inverse video.

Similarly for mouse over text: M-x customize-option RET mouse-highlight which I disable.

Friday, July 16, 2010

Emacs, mozrepl and javascript autotesting

Emacs, mozrepl and javascript autotesting

This article shows how to use mozrepl in conjunction with emacs to run tests (or some other function) automatically in a web page in your browser as you work on a related javascript file in emacs.

This is not some perfect setup. And given how quickly things change these days it may be hard to replicate. But it shows the power of several different technologies interacting to give us more freedom in what we do and how we do it.

  • To follow this blog post, you need to:
    • install mozrepl
      • mozrepl is a firefox addon; there is an older version called mozlab; you should go here instead though where you should find a link for the .xpi file
      • after restarting firefox, you should be able to telnet to the js repl
          bash> telnet localhost 4242
          ... [header stuff]...
          repl1>
        
        • this is a nice little repl; you can experiment with javascript here and test things out; you might want to check out the tutorial
        • of course, doing it in a telnet program isn't so much fun; you could wrap it in readline library such as:
          bash> rlwrap telnet localhost 4242
          ... [header stuff]...
          repl1>
          
        • this should give you similar functionality that you'd expect on the bash prompt
        • of course, there's arguably a better solution still, which is to run it in emacs since this will allow you to
          • edit javascript files and send parts or all thereof to mozrepl directly, and
          • generate command strings dynamically in emacs and send these directly to mozrepl
      • which leads us to mozrepl.el ...
    • install mozrepl.el in your emacs
      • instructions are here
      • I should note that the javascript mode I'm using in emacs comes from here
      • and my mozrepl.el comes from another emacs mode: nxhtml mode
      • these were some additional setup lines in my .emacs
          (add-to-list 'auto-mode-alist '("\.js$" . js-mode))
          (autoload 'inferior-moz-mode "moz" "MozRepl Inferior Mode" t)
          (autoload 'moz-minor-mode "moz" "MozRepl Minor Mode" t)
          (add-hook 'js-mode-hook 'javascript-moz-setup)
          (defun javascript-moz-setup ()
            (interactive)
            (moz-minor-mode 1))
        
      • at the moment, javascript development in emacs seems to be in a state of flux with several js/javascript mode versions floating around; getting set up can be confusing and is beyond what I am trying to share here
      • you should be able to perform this command in your emacs (or something like it)
        M-x run-mozilla
        

        and have a new buffer open up with a repl prompt similar to the telnet experience above.

Putting it together

My set up has the following features:

  • I use a home-grown test framework called unitjs that allows me to group my tests into sections, and group these sections into modules (functions) that I can run either when the page loads, or on clicking a button (etc)
  • I have an html page for testing that loads my js project files and the testing framework I am using to test the project as well as the tests themselves
  • these tests are not run automatically but sit in functions (which I loosely refer to as modules)
  • for instance, I might have
    var tests = {};
    ...
    tests.module1 = function() {
      ... do some setup ...
      ... define some test functions with assertions ...
      ... call the test runner to run the tests above and collect the results ...
    }
    
  • each module corresponds to a separate js file in the tests folder of my project
    • this is important for the setup I am demonstrating as will be shown shortly
  • to run the tests for module1, for instance, you just need to invoke the function
    tests.module1()
    

    and the results will get displayed on the test page

  • similarly for tests.module2 and so on...

Hooking up emacs, mozrepl and autotesting

What we're going to do now is get emacs to automagically work out which test module file we have just saved and send the command (tests.moduleX()) to mozrepl, which will then execute this command within the context of our test page, thereby running and displaying the tests

  • in your .emacs file we set up a function that does the job of reloading the page and sending the test instructions:

      (defun me/mozrepl/run-after-reload (str)
       "Send string to mozrepl, but only after reloading"
       (interactive)
       (progn
         (comint-send-string (inferior-moz-process) "repl.home();")
         (comint-send-string (inferior-moz-process) "BrowserReload();")
         (sleep-for 0 500)
         (comint-send-string (inferior-moz-process) "repl.enter(content);")
         (comint-send-string
          (inferior-moz-process) str )))
    
  • [18-Jul-2010]: I've added ';' after each js command in the above defun

  • all we're doing here is sending a series of commands via the repl
    • each comint-send-string command is as though we were typing that command into the repl ourselves
  • note that the commands reload the browser page, then get mozrepl to enter into the context of the document (repl.enter(content)); this gives us access to our javascript code that is loaded on this page
    • you can check by typing into the repl the name of one of your global variables in your javascript project; the repl should have access to it and you should be able to use it
    • when I was playing with mozrepl this wasn't at all obvious and I almost gave up trying to access the javascript that had loaded with my page until I discovered this step
  • once we're in the correct context, we can get the repl to evaluate 'str'
  • note the sleep command; I'm not sure how important this is but I thought it prudent (and may have had trouble otherwise) to give the browser some time to reload before trying to send another command to the repl

    • there may be other ways to do this such as not reloading the browser page and simple insert a script tag into the head node of the document using DOM operations
  • now we add in some functionality that will examine the buffer we are writing our tests in and guesses which test function to send to the repl:

        (defun proj1/tests/run (test-module)
          "Pass test invocation string to me/mozrepl/run-after-reload
          ; eg test-module might be 'tests.module1'
          ; command will be: tests.module1(document.getElementById('tests-container'))"
          (me/mozrepl/run-after-reload
           (concat test-module "(document.getElementById('tests-container'))")))
    
        (defun proj1/find-and-run-test-module ()
          "Look for test module signature; if found, send it to proj1/tests/run"
          (interactive)
          (cond
           ((search "tests.module1 = function" (buffer-string))
            (proj1/tests/run "tests.module1"))
           ((search "tests.module2 = function" (buffer-string))
            (proj1/tests/run "tests.module2")) ))
    
  • the first defun takes a test module name generates the particular command I want mozrepl to evaluate within the context of the testing page:

    "tests.module1(document.getElementById('tests-container'))"
    
    • will be evaluated by the repl within the context of my testing page and will run the module1 tests and pass in a reference to a test-container node (on the testing page) that the results will be displayed in
  • the second defun searches the current buffer and looks for a matching piece of text using the elisp (search ...) function ; in this case, the first part of our definition of the test module is used

    • if it is found, then we invoke the first defun with the relevant module
  • finally, we don't want to have to run M-x proj1/find-and-run-test-module when we are in our test file, so we set up a save hook to do it automatically:

        (defun proj1/autotest () (interactive)
          (add-hook 'after-save-hook 'proj1/find-and-run-test-module 'append 'local))  
    
        (defun proj1/autotest-remove () (interactive)
          (remove-hook 'after-save-hook 'proj1/find-and-run-test-module 'local))
    
  • we invoke the first defun [M-x proj1/autotest] in our buffer just once; thereafter whenever we save, our test page will get reloaded and the test module for that page gets executed

  • the second defun allows us to turn this off
  • And that's pretty much it!

Notes

  • Don't forget:
    • you need to keep your browser open on the testing page with the loaded code
    • You will need to start the repl in emacs (M-x run-mozilla)
  • I haven't figured out how to navigate tabs in mozrepl

Concluding Remarks

  • mozrepl allows you to tinker with live webpages via a javascript repl
  • emacs is great at connecting with repls in general
  • this article was just experimenting with combining these two

Related pages

  • The inspiration for this artice was this page on emacswiki
    • this page shows how to program emacs to send commands to mozrepl
    • it highlights comint mode; one of the things that makes emacs an extremely powerful, versatile editor and which we used above

Friday, April 2, 2010

Learning emacs - programming emacs with elisp - I

I'm learning emacs and wanted to blog about how to script it and make it do things to enhance your productivity. The stuff I'm going to do here is really one step up from being a reasonably proficient user of emacs if that. I'm really only just getting used to lisp and emacs version of it — called elisp.

There is an opportunity here, though. By getting to know emacs better you will have to learn elisp. And by learning elisp, you are really learning a fully-capable programming language and a dialect of lisp. So you get to kill 2 birds with one stone: you get to know one of the most extensible text editors and one of the most extensible programming languages - it's no coincidence the two are related.

Warm up - evaluating some elisp

  • If you're new to emacs, see this link: Getting help in emacs
  • Load up emacs
  • head over to the *scratch* buffer
  • Let's look at one of the most basic operations in emacs: moving the cursor forward. How do we find what function is involved? Type: C-h k C-f . "C-h k" invokes the help function in emacs that is responsible for telling you what a key combination does; the key combination we asked it to look up was "C-f" - which is emacs default way to move the cursor forward. On my emacs, this is bound to "(forward-char &optional n)"[1]. What this means is that it is bound to the function "forward-char" which takes an optional argument "n".
  • So, on a new line in *scratch* type: (forward-char 2) 1234567890 Leave no spaces between your text and the left edge of the buffer.
  • Now put your cursor right at the end of the line with forward-char: ("|" is the position of the cursor below)
                (forward-char 2)|
                1234567890
              
    ... and type C-x C-e
    You cursor should move to here:
                (forward-char 2)
                1|234567890
              
    Try changing 2 to 1 or -1 and see what happens.
    NOTE: always put your cursor right to the end of the line before you type C-x C-e. One easy way to do this is to type C-e before you type C-x C-e
  • What you've done is execute your first lisp program.
  • Another way you could have executed 'forward-char' is via emacs' M-x key; type M-x forward-char and press RETURN and follow the prompts.
  • What you should note is that any function that we run in emacs can be called using S-expressions (using lisp-parlance). Something like this
                (some-function arg1 arg2 ...)
              
    Which in more "mainstream" languages would look more like:
                some_function(arg1,arg2,...)
              
    This is how lisp and scheme work in general. The reasons for surrounding things in brackets runs quite deep. If you want to get into it, google "cons cell", "homoiconic" or just "lisp". For my purposes I'm just showing how to get started programmatically in emacs in this article.

Here's a great little series on lisp programming by James Turner. There are at least 4 parts.

[1] - if you are in viper-mode, you should go into insert mode (press i) and use the emacs key bindings to move around eg C-e and C-x C-e will work in insert mode (my viper experience level is set to 5 so your mileage may vary if you are using a lower level).

Sunday, March 28, 2010

Learning emacs - Getting Help

Emacs is a highly extensible editor - so extensible in fact that it is whatever you want to make it. There are some compelling reasons to get to know emacs, whether you're a die hard unix vi/vim maven or just windows coder. These include: learning lisp, learning clojure (a very young and promising java-based lisp variant with an emphasis on functionaal programming and concurrency) as well as editing xml and xhtml using the nxml and nxhtml modes.

The more comfortable you are with the lisp way of programming and seeing the world, the more likely you'll make emacs your editor of choice or at least more easily appreciate how emacs works and be comfortable with it.

I'm learning both emacs and lisp (in one form or another) so take what I say in this context. Here's a short article on how to get help in emacs.

Getting help in Emacs

  • you should do the tutorial that emacs provides you when you start; this will teach you basic key combinations and basic concepts; you can access this tutorial by typing C-h t .
  • Take the guided tour at http://www.gnu.org/software/emacs/tour/
  • terminology:
    • a "point" is your cursor; there are commands in emacs such as "find file at oint" or "browser url at point" for instance
    • a "region" is an area of the buffer you have highlighted with the cursor; you can do it by holding the mouse-1 button down and dragging; you can also do it from the keyboard using C-SPACE and cursor movement keys
    • a "frame" is what most people refer to as a window; its the thing that has a title bar and quite often a maximize/minimize button
    • a "buffer" is the thing your cursor is inside of; a file you open to edit is represented by a buffer; there are also special buffers that don't represent files on your file system; for instance: emacs logs its messages to a special buffer called *messages*; there is a buffer for listing all buffers open in emacs which you can get using C-x C-b
    • the "mini buffer" is like a small permanent section at the bottom of the emacs frame that shows you what key combinations you are pressing and returns status and help messages; it's the main feedback area for when you run commands
    • a "window" is the thing a buffer sits inside of; you can view more than one window (and its corresponding buffer) in the current frame, sometimes referred to as "splitting windows"
    • You can practise some of the keys that modify windows and buffers (frames are things you can worry about later):
      C-x 2 horizontally splits your current window into 2 windows;
      C-x 3 vertically splits current window into 2 windows
      C-x 1 gets rid of any other split windows and keeps the one your cursor is in
      C-x 0 if you have at least 2 split windows, this hides (unspits) the window you are in and puts your cursor into another one
      Often with message or error or output buffers - buffers that are created or shown as a result of some action you have just performed - you can close or hide them with the 'q' key.
      C-x 4 0 kills the buffer and hides (unsplits) the window (you might find it easier to type 'q' in some situations although this might not kill the buffer)
      C-x o to move between split windows
  • M-x is the basic prefix to access what emacs refers to as "interactive" commands; everything emacs does can be found this way; not convinced, then type: C-h k C-f to look up what C-f ("move cursor forward" command) uses; there are other "commands" or "functions" which are not interactive and which you cannot directly access via M-x; basically emacs can either expose a command directly to a user via M-x (interactive) or or not; this makes sense, if you're building some new nifty functionality into emacs you will likely end up writing some lower level routines which support higher level interactive ones and which you wouldn't want the user to run by themselves via M-x.
    More to the point, the M-x command leads us into the heart of emacs extensibility; emacs is a bunch of commands and functions written in a variant of lisp called elisp*. If you're not familiar with lisp you might wonder why all the function names are hyphenated and what's really going on and how on earth you might script them (something I might blog about later and which you can read about easily enough on other blogs and using the Gnu manuals (below)). As mentioned above, I think it's worth understanding lisp and elisp a little to grok what's going on (I don't mean you have to straight away, but over time) which leads to the next point...
    [* some of the functionality is written in C but exposed to elisp]
  • There are 3 big official manuals you should know about:
  • getting help; emacs has all sorts of ways to provide you to search and explore what it can do; it just requires you to know how to access it!
    • C-h C-h loads a general help and other C-h * combinations you can use
    • C-h m documents the mode of the current buffer you are in; don't forget to use C-M-v to scroll the help buffer whilst keeping your point in the original buffer; if you want to search in this help buffer, C-x o will move your point into it; type q to hide the help buffer and its window
    • C-h k describes what a given key combination does - what function it calls
    • C-h f describes a function
    • C-h b lists current key bindings
    • C-h w tells you if a function has a key combination
    • M-x apropos does a search on commands in emacs; try "M-x apropos buffer" to look up all commands that have the word buffer in them; C-x o into this buffer and do a search on "kill" and "rename" (C-s kill etc ...); apropos shows more than just interactive functions so some of what you see may not be accessible via M-x