Line 3: |
Line 3: |
| [http://omni.isr.ist.utl.pt/~etienne/EmacsEditingOctaveCode.jpg Emacs Editing Octave Code] | | [http://omni.isr.ist.utl.pt/~etienne/EmacsEditingOctaveCode.jpg Emacs Editing Octave Code] |
| | | |
− | Features & bugs:
| + | = Emacs Octave Support = |
− | * Highlighting of keywords and comments
| |
− | * Auto-indentation
| |
− | * Some annoying bugs in the above
| |
| | | |
− | == See also == | + | The development of Octave code can greatly be facilitated using Emacs |
− | * [http://www.gnu.org/software/octave/doc/interpreter/Emacs-Octave-Support.html Octave Manual: Appendix H Emacs Octave Support]
| + | with Octave mode, a major mode for editing Octave files which can, for |
| + | example: |
| + | |
| + | * automatically indent the code |
| + | * do some of the typing (with Abbrev mode) |
| + | * highlight keywords, comments, strings, etc. in different faces (with Font-lock mode on devices that support it). |
| + | |
| + | It is also possible to run Octave from within Emacs, either by directly |
| + | entering commands at the prompt in a buffer in Inferior Octave mode, or |
| + | by interacting with Octave from within a file with Octave code. This is |
| + | useful in particular for debugging Octave code. |
| + | |
| + | Finally, you can convince Octave to use the Emacs info reader for |
| + | {{codeline|help -i}}. |
| + | |
| + | All functionality is provided by the Emacs Lisp package EOS (Emacs |
| + | Octave Support). |
| + | |
| + | Please contact [mailto:Kurt.Hornik@wu-wien.ac.at Kurt Hornik] if you have |
| + | any questions or suggestions on using EOS. |
| + | |
| + | == Installing EOS == |
| + | |
| + | The Emacs package EOS consists of the three files {{Path|octave-mod.el}}, |
| + | {{Path|octave-inf.el}}, and {{Path|octave-hlp.el}}. These files, |
| + | or better yet their byte-compiled versions, should be somewhere in your Emacs |
| + | load-path. |
| + | |
| + | If you have GNU Emacs with a version number at least as high as 19.35, |
| + | you are all set up, because EOS is respectively will be part of GNU |
| + | Emacs as of version 19.35. |
| + | |
| + | Otherwise, copy the three files from the {{Path|emacs}} subdirectory of |
| + | the Octave distribution to a place where Emacs can find them (this |
| + | depends on how your Emacs was installed). Byte-compile them for speed |
| + | if you want. |
| + | |
| + | == Using Octave Mode == |
| + | |
| + | If you are lucky, your sysadmins have already arranged everything so |
| + | that Emacs automatically goes into Octave mode whenever you visit an |
| + | Octave code file as characterized by its extension {{Path|.m}}. |
| + | If not, proceed as follows. |
| + | |
| + | <ol> |
| + | <li>To begin using Octave mode for all {{Path|.m}} files you visit, add the following lines to a file loaded by Emacs at startup time, typically your {{Path|~/.emacs}} file:</li> |
| + | <pre> |
| + | (autoload 'octave-mode "octave-mod" nil t) |
| + | (setq auto-mode-alist |
| + | (cons '("\\.m$" . octave-mode) auto-mode-alist)) |
| + | </pre> |
| + | <li>Finally, to turn on the abbrevs, auto-fill and font-lock features automatically, also add the following lines to one of the Emacs startup files:</li> |
| + | <pre> |
| + | (add-hook 'octave-mode-hook |
| + | (lambda () |
| + | (abbrev-mode 1) |
| + | (auto-fill-mode 1) |
| + | (if (eq window-system 'x) |
| + | (font-lock-mode 1)))) |
| + | </pre> |
| + | </ol> |
| + | See the Emacs manual for more information about how to customize |
| + | Font-lock mode. |
| + | |
| + | In Octave mode, the following special Emacs commands can be used in |
| + | addition to the standard Emacs commands. |
| + | |
| + | ; {{key press|C-h|m}} |
| + | : Describe the features of Octave mode. |
| + | |
| + | ; {{key press|LFD}} |
| + | : Reindent the current Octave line, insert a newline and indent the new line ({{codeline|octave-reindent-then-newline-and-indent}}). An abbrev before point is expanded if {{codeline|abbrev-mode}} is non-{{codeline|nil}}. |
| + | |
| + | ; {{key press|TAB}} |
| + | : Indents current Octave line based on its contents and on previous lines ({codeline|indent-according-to-mode}}). |
| + | |
| + | ; {{key press|;}} |
| + | : Insert an "electric" semicolon ({codeline|octave-electric-semi}}). If {{codeline|octave-auto-indent}} is non-{{codeline|nil}}, reindent the current line. If {{codeline|octave-auto-newline}} is non-{{codeline|nil}}, automagically insert a newline and indent the new line. |
| + | |
| + | ; {{key press|`}} |
| + | : Start entering an abbreviation ({{codeline|octave-abbrev-start}}). If Abbrev mode is turned on, typing {{key press|`C-h}} or {{key press|`?}} lists all abbrevs. Any other key combination is executed normally. Note that all Octave abbrevs start with a grave accent. |
| + | |
| + | ; {{key press|M-LFD}} |
| + | : Break line at point and insert continuation marker and alignment ({{codeline|octave-split-line}}). |
| + | |
| + | ; {{key press|M-TAB}} |
| + | : Perform completion on Octave symbol preceding point, comparing that symbol against Octave's reserved words and built-in variables ({{codeline|octave-complete-symbol}}). |
| + | |
| + | ; {{key press|M-C-a}} |
| + | : Move backward to the beginning of a function ({{codeline|octave-beginning-of-defun}}). With prefix argument {{codeline|N}}, do it that many times if {codeline|N}} is positive; otherwise, move forward to the {codeline|N}}-th following beginning of a function. |
| + | |
| + | ; {{key press|M-C-e}} |
| + | : Move forward to the end of a function ({{codeline|octave-end-of-defun}}). With prefix argument {{codeline|N}}, do it that many times if {{codeline|N}} is positive; otherwise, move back to the {{codeline|N}}-th preceding end of a function. |
| + | |
| + | ; {{key press|M-C-h}} |
| + | : Puts point at beginning and mark at the end of the current Octave function, i.e., the one containing point or following point ({{codeline|octave-mark-defun}}). |
| + | |
| + | ; {{key press|M-C-q}} |
| + | : Properly indents the Octave function which contains point ({{codeline|octave-indent-defun}}). |
| + | |
| + | ; {{key press|M-;}} |
| + | : If there is no comment already on this line, create a code-level comment (started by two comment characters) if the line is empty, or an in-line comment (started by one comment character) otherwise ({{codeline|octave-indent-for-comment}}). Point is left after the start of the comment which is properly aligned. |
| + | |
| + | ; {{key press|C-c|;}} |
| + | : Puts the comment character {{codeline|#}} (more precisely, the string value of {{codeline|octave-comment-start}}) at the beginning of every line in the region ({{codeline|octave-comment-region}}). With just {{key press|C-u}} prefix argument, uncomment each line in the region. A numeric prefix argument {{codeline|N}} means use {{codeline|N}} comment characters. |
| + | |
| + | ; {{key press|C-c|:}} |
| + | : Uncomments every line in the region ({{codeline|octave-uncomment-region}}). |
| + | |
| + | ; {{key press|C-c|C-p}} |
| + | : Move one line of Octave code backward, skipping empty and comment lines ({{codeline|octave-previous-code-line}}). With numeric prefix argument {{codeline|N}}, move that many code lines backward (forward if {{codeline|N}} is negative). |
| + | |
| + | ; {{key press|C-c|C-n}} |
| + | : Move one line of Octave code forward, skipping empty and comment lines ({{codeline|octave-next-code-line}}). With numeric prefix argument {{codeline|N}}, move that many code lines forward (backward if {{codeline|N}} is negative). |
| + | |
| + | ; {{key press|C-c|C-a}} |
| + | : Move to the `real' beginning of the current line |
| + | ({{codeline|octave-beginning-of-line}}). If point is in an empty or comment line, simply go to its beginning; otherwise, move backwards to the beginning of the first code line which is not inside a continuation statement, i.e., which does not follow a code line ending in {{codeline|...}} or {{codeline|\}}, or is inside an open parenthesis list. |
| + | |
| + | ; {{key press|C-c|C-e}} |
| + | : Move to the `real' end of the current line ({{codeline|octave-end-of-line}}). If point is in a code line, move forward to the end of the first Octave code line which does not end in {{codeline|...}} or {{codeline|\}} or is inside an open parenthesis list. Otherwise, simply go to the end of the current line. |
| + | |
| + | ; {{key press|C-c|M-C-n}} |
| + | : Move forward across one balanced begin-end block of Octave code ({{codeline|octave-forward-block}}). With numeric prefix argument {{codeline|N}}, move forward across {{codeline|n}} such blocks (backward if {{codeline|N}} is negative). |
| + | |
| + | ; {{key press|C-c|M-C-p}} |
| + | : Move back across one balanced begin-end block of Octave code ({{codeline|octave-backward-block}}). With numeric prefix argument {{codeline|N}}, move backward across {{codeline|N}} such blocks (forward if {{codeline|N}} is negative). |
| + | |
| + | ; {{key press|C-c|M-C-d}} |
| + | : Move forward down one begin-end block level of Octave code ({{codeline|octave-down-block}}). With numeric prefix argument, do it that many times; a negative argument means move backward, but still go down one level. |
| + | |
| + | ; {{key press|C-c|M-C-u}} |
| + | : Move backward out of one begin-end block level of Octave code ({{codeline|octave-backward-up-block}}). With numeric prefix argument, do it that many times; a negative argument means move forward, but still to a less deep spot. |
| + | |
| + | ; {{key press|C-c|M-C-h}} |
| + | : Put point at the beginning of this block, mark at the end ({{codeline|octave-mark-block}}). The block marked is the one that contains point or follows point. |
| + | |
| + | ; {{key press|C-c|]}} |
| + | : Close the current block on a separate line ({{codeline|octave-close-block}}). An error is signaled if no block to close is found. |
| + | |
| + | ; {{key press|C-c|f}} |
| + | : Insert a function skeleton, prompting for the function's name, arguments and return values which have to be entered without parentheses ({{codeline|octave-insert-defun}}). |
| + | |
| + | ; {{key press|C-c|C-h}} |
| + | : Search the function, operator and variable indices of all info files with documentation for Octave for entries ({{codeline|octave-help}}). If used interactively, the entry is prompted for with completion. If multiple matches are found, one can cycle through them using the standard {{codeline|,}} ({{codeline|Info-index-next}}) command of the Info reader. |
| + | : |
| + | : The variable {{codeline|octave-help-files}} is a list of files to search through and defaults to {{codeline|'("octave")}}. If there is also an Octave Local Guide with corresponding info file, say, {{Path|octave-LG}}, you can have {{codeline|octave-help}} search both files by {{codeline|(setq octave-help-files '("octave" "octave-LG"))}} in one of your Emacs startup files. |
| + | |
| + | A common problem is that the {{key press|RET}} key does ''not'' indent the |
| + | line to where the new text should go after inserting the newline. This |
| + | is because the standard Emacs convention is that {{key press|RET}} (aka |
| + | {{key press|C-m}}) just adds a newline, whereas {{key press|LFD}} (aka {{key press|C-j}}) adds a |
| + | newline and indents it. This is particularly inconvenient for users with |
| + | keyboards which do not have a special {{key press|LFD}} key at all; in such |
| + | cases, it is typically more convenient to use {{key press|RET}} as the {{key press|LFD}} |
| + | key (rather than typing {{key press|C-j}}). |
| + | |
| + | You can make {{key press|RET}} do this by adding |
| + | |
| + | <pre> |
| + | (define-key octave-mode-map "\C-m" |
| + | 'octave-reindent-then-newline-and-indent) |
| + | </pre> |
| + | |
| + | to one of your Emacs startup files. Another, more generally applicable |
| + | solution is |
| + | |
| + | <pre> |
| + | (defun RET-behaves-as-LFD () |
| + | (let ((x (key-binding "\C-j"))) |
| + | (local-set-key "\C-m" x))) |
| + | (add-hook 'octave-mode-hook 'RET-behaves-as-LFD) |
| + | </pre> |
| + | |
| + | (this works for all modes by adding to the startup hooks, without having |
| + | to know the particular binding of {{key press|RET}} in that mode!). Similar |
| + | considerations apply for using {{key press|M-RET}} as {{key press|M-LFD}}. As |
| + | [mailto:bwarsaw@cnri.reston.va.us Barry A. Warsaw] says in the documentation for his |
| + | {{codeline|cc-mode}}, "This is a very common question. :-) If you want |
| + | this to be the default behavior, don't lobby me, lobby RMS!" |
| + | |
| + | The following variables can be used to customize Octave mode. |
| + | |
| + | ; {{codeline|octave-auto-indent}} |
| + | : Non-{{codeline|nil}} means auto-indent the current line after a semicolon or space. Default is {{codeline|nil}}. |
| + | |
| + | ; {{codeline|octave-auto-newline}} |
| + | : Non-{{codeline|nil}} means auto-insert a newline and indent after semicolons are typed. The default value is {{codeline|nil}}. |
| + | |
| + | ; {{codeline|octave-blink-matching-block}} |
| + | : Non-{{codeline|nil}} means show matching begin of block when inserting a space, newline or {{codeline|;}} after an else or end keyword. Default is {{codeline|t}}. This is an extremely useful feature for automatically verifying that the keywords match --- if they don't, an error message is displayed. |
| + | |
| + | ; {{codeline|octave-block-offset}} |
| + | : Extra indentation applied to statements in block structures. Default is 2. |
| + | |
| + | ; {{codeline|octave-continuation-offset}} |
| + | : Extra indentation applied to Octave continuation lines. Default is 4. |
| + | |
| + | ; {{codeline|octave-continuation-string}} |
| + | : String used for Octave continuation lines. Normally {{codeline|\}}. |
| + | |
| + | ; {{codeline|octave-mode-startup-message}} |
| + | : If {{codeline|t}} (default), a startup message is displayed when Octave mode is called. |
| + | |
| + | If Font Lock mode is enabled, Octave mode will display |
| + | |
| + | * strings in {{codeline|font-lock-string-face}} |
| + | |
| + | * comments in {{codeline|font-lock-comment-face}} |
| + | |
| + | * the Octave reserved words (such as all block keywords) and the text functions (such as {{codeline|cd}} or {{codeline|who}}) which are also reserved using {{codeline|font-lock-keyword-face}} |
| + | |
| + | * the built-in operators ({{codeline|&&}}, {{codeline|<nowiki>==</nowiki>}}, {{codeline|...}}) using {{codeline|font-lock-reference-face}} |
| + | |
| + | * and the function names in function declarations in {{codeline|font-lock-function-name-face}}. |
| + | |
| + | There is also rudimentary support for Imenu (currently, function |
| + | names can be indexed). |
| + | |
| + | You can generate {{Path|TAGS}} files for Emacs from Octave {{Path|.m}} files using |
| + | the shell script {{codeline|octave-tags}} that is installed alongside your copy of |
| + | Octave. |
| + | |
| + | Customization of Octave mode can be performed by modification of the |
| + | variable {{codeline|octave-mode-hook}}. If the value of this variable is |
| + | non-{{codeline|nil}}, turning on Octave mode calls its value. |
| + | |
| + | If you discover a problem with Octave mode, you can conveniently send a |
| + | bug report using {{key press|C-c|C-b}} ({{codeline|octave-submit-bug-report}}). This |
| + | automatically sets up a mail buffer with version information already |
| + | added. You just need to add a description of the problem, including a |
| + | reproducible test case and send the message. |
| + | |
| + | == Running Octave from Within Emacs == |
| + | |
| + | The package octave provides commands for running an inferior |
| + | Octave process in a special Emacs buffer. Use |
| + | {{key press|M-x}} {{codeline|run-octave}} |
| + | to directly start an inferior Octave process. If Emacs does not know |
| + | about this command, add the line |
| + | {{codeline|(autoload 'run-octave "octave-inf" nil t)}} |
| + | to your {{Path|.emacs}} file. |
| + | |
| + | This will start Octave in a special buffer the name of which is |
| + | specified by the variable {{codeline|inferior-octave-buffer}} and defaults to |
| + | "*Inferior Octave*". From within this buffer, you can |
| + | interact with the inferior Octave process as usual, i.e., by entering |
| + | Octave commands at the prompt. The buffer is in Inferior Octave mode, |
| + | which is derived from the standard Comint mode, a major mode for |
| + | interacting with an inferior interpreter. See the documentation for |
| + | {{codeline|comint-mode}} for more details, and use {{key press|C-h|b}} to find out |
| + | about available special keybindings. |
| + | |
| + | You can also communicate with an inferior Octave process from within |
| + | files with Octave code (i.e., buffers in Octave mode), using the |
| + | following commands. |
| + | |
| + | ; {{key press|C-c|i|l}} |
| + | : Send the current line to the inferior Octave process ({{codeline|octave-send-line}}). With positive prefix argument {{codeline|N}}, send that many lines. If {{codeline|octave-send-line-auto-forward}} is non-{{codeline|nil}}, go to the next unsent code line. |
| + | |
| + | ; {{key press|C-c|i|b}} |
| + | : Send the current block to the inferior Octave process ({{codeline|octave-send-block}}). |
| + | |
| + | ; {{key press|C-c|i|f}} |
| + | : Send the current function to the inferior Octave process ({{codeline|octave-send-defun}}). |
| + | |
| + | ; {{key press|C-c|i|r}} |
| + | : Send the region to the inferior Octave process ({{codeline|octave-send-region}}). |
| + | |
| + | ; {{key press|C-c|i|s}} |
| + | : Make sure that `inferior-octave-buffer' is displayed ({{codeline|octave-show-process-buffer}}). |
| + | |
| + | ; {{key press|C-c|i|h}} |
| + | : Delete all windows that display the inferior Octave buffer ({{codeline|octave-hide-process-buffer}}). |
| + | |
| + | ; {{key press|C-c|i|k}} |
| + | : Kill the inferior Octave process and its buffer ({{codeline|octave-kill-process}}). |
| + | |
| + | The effect of the commands which send code to the Octave process can be |
| + | customized by the following variables. |
| + | |
| + | ; {{codeline|octave-send-echo-input}} |
| + | : Non-{{codeline|nil}} means echo input sent to the inferior Octave process. Default is {{codeline|t}}. |
| + | |
| + | ; {{codeline|octave-send-show-buffer}} |
| + | Non-{{codeline|nil}} means display the buffer running the Octave process after sending a command (but without selecting it). Default is {{codeline|t}}. |
| + | |
| + | If you send code and there is no inferior Octave process yet, it will be |
| + | started automatically. |
| + | |
| + | The startup of the inferior Octave process is highly customizable. |
| + | The variable {{codeline|inferior-octave-startup-args}} can be used for |
| + | specifying command lines arguments to be passed to Octave on startup |
| + | as a list of strings. For example, to suppress the startup message and |
| + | use traditional mode, set this to {{codeline|'("-q" "--traditional")}}. |
| + | You can also specify a startup file of Octave commands to be loaded on |
| + | startup; note that these commands will not produce any visible output |
| + | in the process buffer. Which file to use is controlled by the variable |
| + | {{codeline|inferior-octave-startup-file}}. If this is {{codeline|nil}}, the file |
| + | {{Path|~/.emacs-octave}} is used if it exists. |
| + | |
| + | And finally, {{codeline|inferior-octave-mode-hook}} is run after starting the |
| + | process and putting its buffer into Inferior Octave mode. Hence, if you |
| + | like the up and down arrow keys to behave in the interaction buffer as |
| + | in the shell, and you want this buffer to use nice colors, add |
| + | |
| + | <pre> |
| + | (add-hook 'inferior-octave-mode-hook |
| + | (lambda () |
| + | (turn-on-font-lock) |
| + | (define-key inferior-octave-mode-map [up] |
| + | 'comint-previous-input) |
| + | (define-key inferior-octave-mode-map [down] |
| + | 'comint-next-input))) |
| + | </pre> |
| + | |
| + | to your {{Path|.emacs}} file. You could also swap the roles of {{key press|C-a}} |
| + | ({{codeline|beginning-of-line}}) and {{key press|C-c|C-a}} ({{codeline|comint-bol}}) using |
| + | this hook. |
| + | |
| + | Note that if you set your Octave prompts to something different |
| + | from the defaults, make sure that {{codeline|inferior-octave-prompt}} matches |
| + | them. Otherwise, ''nothing'' will work, because Emacs will not know |
| + | when Octave is waiting for input, or done sending output. |
| + | |
| + | == Using the Emacs Info Reader for Octave == |
| + | |
| + | You may also use the Emacs Info reader with Octave's {{codeline|doc}} function. |
| + | For this, the package gnuserv needs to be installed. |
| + | |
| + | If gnuserv is installed, add the lines |
| + | |
| + | <pre> |
| + | (autoload 'octave-help "octave-hlp" nil t) |
| + | (require 'gnuserv) |
| + | (gnuserv-start) |
| + | </pre> |
| + | |
| + | to your {{Path|.emacs}} file. |
| + | |
| + | You can use either plain Emacs Info or the function {{codeline|octave-help}} |
| + | as your Octave info reader (for {{codeline|help -i}}). In the former case, |
| + | use {{codeline|info_program ("info-emacs-info")}}. |
| + | The latter is perhaps more attractive because it allows one to look up keys |
| + | in the indices of several info files related to Octave (provided |
| + | that the Emacs variable {{codeline|octave-help-files}} is set correctly). In |
| + | this case, use {{codeline|info_program ("info-emacs-octave-help")}}. |
| + | |
| + | If you use Octave from within Emacs, it is best to add these settings to |
| + | your {{Path|~/.emacs-octave}} startup file (or the file pointed to by the |
| + | Emacs variable {{codeline|inferior-octave-startup-file}}). |
| | | |
| [[Category:Editors]] | | [[Category:Editors]] |