Summary: Editors such as Vim and Sublime Text are essentially editors.emacs are essentially a combination of functions.
Emacs is essentially a combination of functions
How emacs differ from help
Editors such as Vim and Sublime Text are essentially editors.
For example, if we look at vim's help, it's in this style. For example, if i want to see the help of the i command:
<insert> or *i* *insert* *<Insert>* i Insert text before the cursor [count] times. When using CTRL-O in Insert mode |i_CTRL-O| the count is not supported.
Look at emacs'help again. It's in this style. For example, let's look at the help of the Ctrl-n key:
C-n runs the command next-line (found in global-map), which is an interactive compiled Lisp function in 'simple.el'. It is bound to C-n. (next-line &optional ARG TRY-VSCROLL) This function is for interactive use only; in Lisp code use 'forward-line' instead. Move cursor vertically down ARG lines. Interactively, vscroll tall lines if 'auto-window-vscroll' is enabled. Non-interactively, use TRY-VSCROLL to control whether to vscroll tall lines: if either 'auto-window-vscroll' or TRY-VSCROLL is nil, this function will not vscroll. ARG defaults to 1. If there is no character in the target line exactly under the current column, the cursor is positioned after the character in that line which spans this column, or at the end of the line if it is not long enough. If there is no line in the buffer after this one, behavior depends on the value of 'next-line-add-newlines'. If non-nil, it inserts a newline character to create a line, and moves the cursor to that line. Otherwise it moves the cursor to the end of the buffer. If the variable 'line-move-visual' is non-nil, this command moves by display lines. Otherwise, it moves by buffer lines, without taking variable-width characters or continued lines into account. See M-x next-logical-line for a command that always moves by buffer lines. The command C-x C-n can be used to create a semipermanent goal column for this command. Then instead of trying to move exactly vertically (or as close as possible), this command moves to the specified goal column (or as close as possible). The goal column is stored in the variable 'goal-column', which is nil when there is no goal column. Note that setting 'goal-column' overrides 'line-move-visual' and causes this command to move by buffer lines rather than by display lines.
Further, we can click simple.el to go in and see its source code:
(defun next-line (&optional arg try-vscroll) "Move cursor vertically down ARG lines. ...Just the help you posted above, skipped here " (declare (interactive-only forward-line)) (interactive "^p\np") (or arg (setq arg 1)) (if (and next-line-add-newlines (= arg 1)) (if (save-excursion (end-of-line) (eobp)) ;; When adding a newline, don't expand an abbrev. (let ((abbrev-mode nil)) (end-of-line) (insert (if use-hard-newlines hard-newline "\n"))) (line-move arg nil nil try-vscroll)) (if (called-interactively-p 'interactive) (condition-case err (line-move arg nil nil try-vscroll) ((beginning-of-buffer end-of-buffer) (signal (car err) (cdr err)))) (line-move arg nil nil try-vscroll))) nil)
As you can see from the above, emacs is a simpler and more direct person than vim, which is a relatively black box and requires a description of the document.Simply put, it's basically a combination of functions that we call directly when we edit.For convenience, we bind these functions to shortcuts.
As long as you know which function to call and don't want to remember any shortcuts, you just need to remember one, Alt+X, and then you can enter the name of the function to execute to execute the command.
Emacs functions are implemented by functions implemented in lisp or C. All sources are open. In the new version, they can be viewed directly through the help function, which is very convenient.
In emacs, commands for the Alt key can also be implemented by pressing Esc before pressing another key.
Different emacs in the direction of expansion
Extension of vim
Emacs was the first well-known editor known for its extensibility, and mainstream editors at the same time learned from Emacs in this respect.Editors such as Sublime Text and Vim now have extensions that are commendable and popular.
However, whether it's Vim, Sublime Text, or even the more powerful Visual Studio Code and Atom, they all open up the extended interface, and everyone writes the extension according to the open interface.
For example, let's look at vim first. Take my vim 8.0.600 on mac OS for example, which supports the following feature s:
Huge version without GUI. Features included (+) or not (-): +acl +clipboard +dialog_con +file_in_path +job -lua +mouse_sgr +path_extra +rightleft +tag_old_static +user_commands +writebackup +arabic +cmdline_compl +diff +find_in_path +jumplist +menu -mouse_sysmouse +perl +ruby -tag_any_white +vertsplit -X11 +autocmd +cmdline_hist +digraphs +float +keymap +mksession +mouse_urxvt +persistent_undo +scrollbind -tcl +virtualedit -xfontset -balloon_eval +cmdline_info -dnd +folding +lambda +modify_fname +mouse_xterm +postscript +signs +termguicolors +visual -xim -browse +comments -ebcdic -footer +langmap +mouse +multi_byte +printer +smartindent +terminfo +visualextra -xpm ++builtin_terms +conceal +emacs_tags +fork() +libcall -mouseshape +multi_lang +profile +startuptime +termresponse +viminfo -xsmp +byte_offset +cryptv +eval -gettext +linebreak +mouse_dec -mzscheme +python +statusline +textobjects +vreplace -xterm_clipboard +channel +cscope +ex_extra -hangul_input +lispindent -mouse_gpm +netbeans_intg -python3 -sun_workshop +timers +wildignore -xterm_save +cindent +cursorbind +extra_search +iconv +listcmds -mouse_jsbterm +num64 +quickfix +syntax +title +wildmenu -clientserver +cursorshape +farsi +insert_expand +localmap +mouse_netterm +packages +reltime +tag_binary -toolbar +windows
The plus sign is a feature supported by VIM installed by me, and the minus sign is not supported.As you can see, I use this version of vim support: python, ruby, perl, and not python3,tcl, and lua to write extensions.
For example, let's look at an official example of the vim extension:
1 " Vim global plugin for correcting typing mistakes 2 " Last Change: 2000 Oct 15 3 " Maintainer: Bram Moolenaar <Bram@vim.org> 4 " License: This file is placed in the public domain. 5 6 if exists("g:loaded_typecorr") 7 finish 8 endif 9 let g:loaded_typecorr = 1 10 11 let s:save_cpo = &cpo 12 set cpo&vim 13 14 iabbrev teh the 15 iabbrev otehr other 16 iabbrev wnat want 17 iabbrev synchronisation 18 \ synchronization 19 let s:count = 4 20 21 if !hasmapto('<Plug>TypecorrAdd') 22 map <unique> <Leader>a <Plug>TypecorrAdd 23 endif 24 noremap <unique> <script> <Plug>TypecorrAdd <SID>Add 25 26 noremenu <script> Plugin.Add\ Correction <SID>Add 27 28 noremap <SID>Add :call <SID>Add(expand("<cword>"), 1)<CR> 29 30 function s:Add(from, correct) 31 let to = input("type the correction for " . a:from . ": ") 32 exe ":iabbrev " . a:from . " " . to 33 if a:correct | exe "normal viws\<C−R>\" \b\e" | endif 34 let s:count = s:count + 1 35 echo s:count . " corrections now" 36 endfunction 37 38 if !exists(":Correct") 39 command −nargs=1 Correct :call s:Add(<q−args>, 0) 40 endif 41 42 let &cpo = s:save_cpo 43 unlet s:save_cpo
In vimscript, the exe command executes the command of vim itself.
Is the API interface invoked anyway, so many languages can be supported.
For example, you can execute a Perl statement directly by: pe perl script.You can view it through: help:perl:
:pe[rl] {cmd} Execute Perl command {cmd}. The current package is "main".
Examples of Perl language write vim plugins:
function! WhitePearl() perl << EOF VIM::Msg("pearls are nice for necklaces"); VIM::Msg("rubys for rings"); VIM::Msg("pythons for bags"); VIM::Msg("tcls????"); EOF endfunction
Common perl callable interfaces are:
:perl VIM::Msg("Text") # displays a message :perl VIM::Msg("Error", "ErrorMsg") # displays an error message :perl VIM::Msg("remark", "Comment") # displays a highlighted message :perl VIM::SetOption("ai") # sets a vim option :perl $nbuf = VIM::Buffers() # returns the number of buffers :perl @buflist = VIM::Buffers() # returns array of all buffers :perl $mybuf = (VIM::Buffers('qq.c'))[0] # returns buffer object for 'qq.c' :perl @winlist = VIM::Windows() # returns array of all windows :perl $nwin = VIM::Windows() # returns the number of windows :perl ($success, $v) = VIM::Eval('&path') # $v: option 'path', $success: 1 :perl ($success, $v) = VIM::Eval('&xyz') # $v: '' and $success: 0 :perl $v = VIM::Eval('expand("<cfile>")') # expands <cfile> :perl $curwin->SetHeight(10) # sets the window height :perl @pos = $curwin->Cursor() # returns (row, col) array :perl @pos = (10, 10) :perl $curwin->Cursor(@pos) # sets cursor to @pos :perl $curwin->Cursor(10,10) # sets cursor to row 10 col 10 :perl $mybuf = $curwin->Buffer() # returns the buffer object for window :perl $curbuf->Name() # returns buffer name :perl $curbuf->Number() # returns buffer number :perl $curbuf->Count() # returns the number of lines :perl $l = $curbuf->Get(10) # returns line 10 :perl @l = $curbuf->Get(1 .. 5) # returns lines 1 through 5 :perl $curbuf->Delete(10) # deletes line 10 :perl $curbuf->Delete(10, 20) # delete lines 10 through 20 :perl $curbuf->Append(10, "Line") # appends a line :perl $curbuf->Append(10, "Line1", "Line2", "Line3") # appends 3 lines :perl @l = ("L1", "L2", "L3") :perl $curbuf->Append(10, @l) # appends L1, L2 and L3 :perl $curbuf->Set(10, "Line") # replaces line 10 :perl $curbuf->Set(10, "Line1", "Line2") # replaces lines 10 and 11 :perl $curbuf->Set(10, @l) # replaces 3 lines
Similarly, py can call python, and rub can use ruby.
Example using python:
:python from vim import * :python from string import upper :python current.line = upper(current.line) :python print "Hello" :python str = current.buffer[42]
Examples of Python calling vim commands:
:py print "Hello" # displays a message :py vim.command(cmd) # execute an Ex command :py w = vim.windows[n] # gets window "n" :py cw = vim.current.window # gets the current window :py b = vim.buffers[n] # gets buffer "n" :py cb = vim.current.buffer # gets the current buffer :py w.height = lines # sets the window height :py w.cursor = (row, col) # sets the window cursor position :py pos = w.cursor # gets a tuple (row, col) :py name = b.name # gets the buffer file name :py line = b[n] # gets a line from the buffer :py lines = b[n:m] # gets a list of lines :py num = len(b) # gets the number of lines :py b[n] = str # sets a line in the buffer :py b[n:m] = [str1, str2, str3] # sets a number of lines at once :py del b[n] # deletes a line :py del b[n:m] # deletes a number of lines
Call python file, which can be called by: pyfile or: pyf command.
Examples of vim plugins written in Ruby:
function! RedGem() ruby << EOF class Garnet def initialize(s) @buffer = VIM::Buffer.current vimputs(s) end def vimputs(s) @buffer.append(@buffer.count,s) end end gem = Garnet.new("pretty") EOF endfunction
Examples of Ruby calling vim interfaces:
print "Hello" # displays a message VIM.command(cmd) # execute an Ex command num = VIM::Window.count # gets the number of windows w = VIM::Window[n] # gets window "n" cw = VIM::Window.current # gets the current window num = VIM::Buffer.count # gets the number of buffers b = VIM::Buffer[n] # gets buffer "n" cb = VIM::Buffer.current # gets the current buffer w.height = lines # sets the window height w.cursor = [row, col] # sets the window cursor position pos = w.cursor # gets an array [row, col] name = b.name # gets the buffer file name line = b[n] # gets a line from the buffer num = b.count # gets the number of lines b[n] = str # sets a line in the buffer b.delete(n) # deletes a line b.append(n, str) # appends a line after n line = VIM::Buffer.current.line # gets the current line num = VIM::Buffer.current.line_number # gets the current line number VIM::Buffer.current.line = "test" # sets the current line number
For another lua language:
function! CurrentLineInfo() lua << EOF local linenr = vim.window().line local curline = vim.buffer()[linenr] print(string.format("Current line [%d] has %d chars", linenr, #curline)) EOF endfunction
tcl language:
function! DefineDate() tcl << EOF proc date {} { return [clock format [clock seconds]] } EOF endfunction
Extensions to Atom
The main language for Atom's extension is CoffeeScript.
YourNameWordCountView = require './your-name-word-count-view' {CompositeDisposable} = require 'atom' module.exports = YourNameWordCount = yourNameWordCountView: null modalPanel: null subscriptions: null activate: (state) -> @yourNameWordCountView = new YourNameWordCountView(state.yourNameWordCountViewState) @modalPanel = atom.workspace.addModalPanel(item: @yourNameWordCountView.getElement(), visible: false) # Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable @subscriptions = new CompositeDisposable # Register command that toggles this view @subscriptions.add atom.commands.add 'atom-workspace', 'your-name-word-count:toggle': => @toggle() deactivate: -> @modalPanel.destroy() @subscriptions.dispose() @wordcountView.destroy() serialize: -> yourNameWordCountViewState: @yourNameWordCountView.serialize() toggle: -> console.log 'YourNameWordCount was toggled!' if @modalPanel.isVisible() @modalPanel.hide() else @modalPanel.show()
Extensions to Visual Studio Code
Plugins for Visual Studio Code can be developed using JavaScript or TypeScript.
Here is an example of an empty TypeScript:
// The module 'vscode' contains the VS Code extensibility API // Import the module and reference it with the alias vscode in your code below import * as vscode from 'vscode'; // this method is called when your extension is activated // your extension is activated the very first time the command is executed export function activate(context: vscode.ExtensionContext) { // Use the console to output diagnostic information (console.log) and errors (console.error) // This line of code will only be executed once when your extension is activated console.log('Congratulations, your extension "my-first-extension" is now active!'); // The command has been defined in the package.json file // Now provide the implementation of the command with registerCommand // The commandId parameter must match the command field in package.json var disposable = vscode.commands.registerCommand('extension.sayHello', () => { // The code you place here will be executed every time your command is executed // Display a message box to the user vscode.window.showInformationMessage('Hello World!'); }); context.subscriptions.push(disposable); }
Extensions to Sublime Text
The extension to Sublime Text is written in Python, for example, to handle carriage return wrapping:
def normalize_line_endings(self, string): string = string.replace('\r\n', '\n').replace('\r', '\n') line_endings = self.view.settings().get('default_line_ending') if line_endings == 'windows': string = string.replace('\n', '\r\n') elif line_endings == 'mac': string = string.replace('\n', '\r') return string
Extensions to emacs
The biggest difference between Emacs and the editors above is that it doesn't matter what extends, it just changes if it doesn't look right.Most of them are functions bound to shortcuts anyway.
For example, in the emacs tutorial, the first function to talk about is find-file, which opens the file and binds it to the C-x C-f key.The official QQ Group Question of Shui Mu Community is to ask what the role of C-x C-f is.
The advantage of Emacs is that there's no secret. Let's look directly at the source code and see what it does:
(defun find-file (filename &optional wildcards) ... ;Documentation omitted (interactive (find-file-read-args "Find file: " (confirm-nonexistent-file-or-buffer))) (let ((value (find-file-noselect filename nil nil wildcards))) (if (listp value) (mapcar 'switch-to-buffer (nreverse value)) (switch-to-buffer value))))
Commands that are so basic are generally unchanged in other editors.However, in spacemacs, C-x C-f binds to the ido-find-file function by default.
(defun ido-find-file () (interactive) (ido-file-internal ido-default-file-method))
ido is a plug-in to Emacs, meaning "Interactive Do", which enhances the basic Emacs functionality in an interactive manner.
Even on older versions of emacs 23.x, ido plug-ins are part of the official release.It's just that the official version of the key binding is still bound to the underlying command.We can choose to bind a key to it or run it through Alt-x.
Later in learning about the capabilities of emacs, we will all talk about how standard Emacs do it and how spacemancs does it.As you can see, there are many standard emacs-bound shortcuts that do not work at all on spacemacs and are bound to other functions.
So instead of remembering shortcuts, remember the function name.It's not too precise, just find it when you lose.When you look for help, you can elevate the key it is bound to, or you can't remember to tie a key you like yourself.
Find help in Emacs
Personally, Emacs does not write as well as Vim's.However, Emacs'documentation is still very rich and we can't find it. We can also look at the code directly.
Documentation on the Official Web
Documentation on the official website is still quite rich: https://www.gnu.org/software/emacs/manual/
In addition to the basic functions, there are also many documents for commonly used large plug-ins, such as I use emacs to write more code, cc-mode to write more detailed documents: https://www.gnu.org/software/emacs/manual/html_node/ccmode/index.html
Find help in emacs
Now that we know that emacs is a combination of functions, it's certainly a call to the appropriate function to provide help.Yes, that's it!
If you want to read the manual completely, you can call the info function, which is bound by default to the C-h i combination.
If you see a handbook or a book about what a shortcut key does, we can look for its corresponding function.Find the definition of a key: C-h k (describe-key): For example, we can check the function of C-h k:
C-h k runs the command describe-key, which is an interactive compiled Lisp function. It is bound to C-h k, <f1> k, <help> k, <menu-bar> <help-menu> <describe> <describe-key-1>. (describe-key &optional KEY UNTRANSLATED UP-EVENT) Display documentation of the function invoked by KEY. KEY can be any kind of a key sequence; it can include keyboard events, mouse events, and/or menu events. When calling from a program, pass KEY as a string or a vector. If non-nil, UNTRANSLATED is a vector of the corresponding untranslated events. It can also be a number, in which case the untranslated events from the last key sequence entered are used. UP-EVENT is the up-event that was discarded by reading KEY, or nil. If KEY is a menu item or a tool-bar button that is disabled, this command temporarily enables it to allow getting help on disabled items and buttons.
As you can see from the help, the shortcut is bound to C-h k, and the function actually called is describe-key.
Similarly, we can query the function of a function through C-h f (describe-function).
describe-function is an interactive compiled Lisp function. It is bound to C-h f, <f1> f, <help> f, <menu-bar> <help-menu> <describe> <describe-function>. (describe-function FUNCTION) Display the full documentation of FUNCTION (a symbol).
In addition, there is a describe-variable function for query variables, bound to the C-h v key.
Summary
- The basic use of emacs is to call some functions.These functions can be called by Alt-x plus the function name.
- Common functions can be bound to shortcuts.Many introductory emacs tutorials cover the use of these features
- info is used to view manuals in emacs, describe-funciton finds function usage, and for lisp functions you can often go directly to the source code.describe-key looks for key-value bindings.Their default bindings are C-h i, C-h f, and C-h k.You'll use them a lot in the years to come