Emacs本质上是函数的组合

从帮助上看emacs有何不同

Vim和Sublime Text等编辑器,本质上是一个编辑器。

比如我们看看vim的帮助,是这个风格的,比如我要看i命令的帮助:

  1. <insert> or *i* *insert* *<Insert>*
  2. i Insert text before the cursor [count] times.
  3. When using CTRL-O in Insert mode |i_CTRL-O| the count
  4. is not supported.

再看看emacs的帮助,是这样的风格,比如我们看Ctrl-n键的帮助:

  1. C-n runs the command next-line (found in global-map), which is an interactive
  2. compiled Lisp function in simple.el’.
  3. It is bound to C-n.
  4. (next-line &optional ARG TRY-VSCROLL)
  5. This function is for interactive use only;
  6. in Lisp code use forward-line instead.
  7. Move cursor vertically down ARG lines.
  8. Interactively, vscroll tall lines if auto-window-vscroll is enabled.
  9. Non-interactively, use TRY-VSCROLL to control whether to vscroll tall
  10. lines: if either auto-window-vscroll or TRY-VSCROLL is nil, this
  11. function will not vscroll.
  12. ARG defaults to 1.
  13. If there is no character in the target line exactly under the current column,
  14. the cursor is positioned after the character in that line which spans this
  15. column, or at the end of the line if it is not long enough.
  16. If there is no line in the buffer after this one, behavior depends on the
  17. value of next-line-add-newlines’. If non-nil, it inserts a newline character
  18. to create a line, and moves the cursor to that line. Otherwise it moves the
  19. cursor to the end of the buffer.
  20. If the variable line-move-visual is non-nil, this command moves
  21. by display lines. Otherwise, it moves by buffer lines, without
  22. taking variable-width characters or continued lines into account.
  23. See M-x next-logical-line for a command that always moves by buffer lines.
  24. The command C-x C-n can be used to create
  25. a semipermanent goal column for this command.
  26. Then instead of trying to move exactly vertically (or as close as possible),
  27. this command moves to the specified goal column (or as close as possible).
  28. The goal column is stored in the variable goal-column’, which is nil
  29. when there is no goal column. Note that setting goal-column
  30. overrides line-move-visual and causes this command to move by buffer
  31. lines rather than by display lines.

更进一步,我们可以点击simple.el进去看看,可以看到它的源码:

  1. (defun next-line (&optional arg try-vscroll)
  2. "Move cursor vertically down ARG lines.
  3. ...就是上面贴过的帮助,此处略过
  4. "
  5. (declare (interactive-only forward-line))
  6. (interactive "^p\np")
  7. (or arg (setq arg 1))
  8. (if (and next-line-add-newlines (= arg 1))
  9. (if (save-excursion (end-of-line) (eobp))
  10. ;; When adding a newline, don't expand an abbrev.
  11. (let ((abbrev-mode nil))
  12. (end-of-line)
  13. (insert (if use-hard-newlines hard-newline "\n")))
  14. (line-move arg nil nil try-vscroll))
  15. (if (called-interactively-p 'interactive)
  16. (condition-case err
  17. (line-move arg nil nil try-vscroll)
  18. ((beginning-of-buffer end-of-buffer)
  19. (signal (car err) (cdr err))))
  20. (line-move arg nil nil try-vscroll)))
  21. nil)

从上面可以看到,比起vim是个相对黑盒,需要文档描述的编辑器,emacs是个比较简单直接的家伙。简单到,基本上就是一堆函数的组合而己,我们做编辑时,就是直接调用这些函数。为了方便,我们把这些函数绑定到快捷键上。

只要知道要调用哪个函数,不想记任何快捷键的话,只需要记住一个就可以了,就是Alt+X,然后就可以输入要执行的函数名,去执行这个命令。

Emacs的功能,都是由lisp或C语言实现的函数来实现的,所有的源码都是开放的,在新的版本中,直接都可以通过帮助功能来查看,非常方便。

在emacs里,Alt键的命令也都可以通过先按Esc再按另一个键的方式来实现。

从扩展方向上看emacs的不同

vim的扩展

Emacs是第一个著名的以可扩展能力而闻名的编辑器,同时期的主流编辑器在这方面都要向emacs学习。到了现在,Sublime Text和Vim等编辑器的扩展功能也是非常值得称道而且受欢迎的。

但是,不管是Vim还是Sublime Text,甚至更强大一些的Visual Studio Code和Atom,它们的做法都是把扩展的接口开放出来,大家按照开放出来的接口来写扩展。

比如我们先看vim,以我在mac OS下的vim 8.0.600为例,它支持下列feature:

  1. Huge version without GUI. Features included (+) or not (-):
  2. +acl +clipboard +dialog_con +file_in_path +job -lua +mouse_sgr +path_extra +rightleft +tag_old_static +user_commands +writebackup
  3. +arabic +cmdline_compl +diff +find_in_path +jumplist +menu -mouse_sysmouse +perl +ruby -tag_any_white +vertsplit -X11
  4. +autocmd +cmdline_hist +digraphs +float +keymap +mksession +mouse_urxvt +persistent_undo +scrollbind -tcl +virtualedit -xfontset
  5. -balloon_eval +cmdline_info -dnd +folding +lambda +modify_fname +mouse_xterm +postscript +signs +termguicolors +visual -xim
  6. -browse +comments -ebcdic -footer +langmap +mouse +multi_byte +printer +smartindent +terminfo +visualextra -xpm
  7. ++builtin_terms +conceal +emacs_tags +fork() +libcall -mouseshape +multi_lang +profile +startuptime +termresponse +viminfo -xsmp
  8. +byte_offset +cryptv +eval -gettext +linebreak +mouse_dec -mzscheme +python +statusline +textobjects +vreplace -xterm_clipboard
  9. +channel +cscope +ex_extra -hangul_input +lispindent -mouse_gpm +netbeans_intg -python3 -sun_workshop +timers +wildignore -xterm_save
  10. +cindent +cursorbind +extra_search +iconv +listcmds -mouse_jsbterm +num64 +quickfix +syntax +title +wildmenu
  11. -clientserver +cursorshape +farsi +insert_expand +localmap +mouse_netterm +packages +reltime +tag_binary -toolbar +windows

带加号的是我装的vim支持的功能,减号为不支持。从中可以看到,我用的这个版本的vim支持:python,ruby,perl三种语言,而不支持python3,tcl和lua语言来写扩展。

比如我们看一个vim扩展的官方例子:

  1. 1 " Vim global plugin for correcting typing mistakes
  2. 2 " Last Change: 2000 Oct 15
  3. 3 " Maintainer: Bram Moolenaar <Bram@vim.org>
  4. 4 " License: This file is placed in the public domain.
  5. 5
  6. 6 if exists("g:loaded_typecorr")
  7. 7 finish
  8. 8 endif
  9. 9 let g:loaded_typecorr = 1
  10. 10
  11. 11 let s:save_cpo = &cpo
  12. 12 set cpo&vim
  13. 13
  14. 14 iabbrev teh the
  15. 15 iabbrev otehr other
  16. 16 iabbrev wnat want
  17. 17 iabbrev synchronisation
  18. 18 \ synchronization
  19. 19 let s:count = 4
  20. 20
  21. 21 if !hasmapto('<Plug>TypecorrAdd')
  22. 22 map <unique> <Leader>a <Plug>TypecorrAdd
  23. 23 endif
  24. 24 noremap <unique> <script> <Plug>TypecorrAdd <SID>Add
  25. 25
  26. 26 noremenu <script> Plugin.Add\ Correction <SID>Add
  27. 27
  28. 28 noremap <SID>Add :call <SID>Add(expand("<cword>"), 1)<CR>
  29. 29
  30. 30 function s:Add(from, correct)
  31. 31 let to = input("type the correction for " . a:from . ": ")
  32. 32 exe ":iabbrev " . a:from . " " . to
  33. 33 if a:correct | exe "normal viws\<C−R>\" \b\e" | endif
  34. 34 let s:count = s:count + 1
  35. 35 echo s:count . " corrections now"
  36. 36 endfunction
  37. 37
  38. 38 if !exists(":Correct")
  39. 39 command nargs=1 Correct :call s:Add(<qargs>, 0)
  40. 40 endif
  41. 41
  42. 42 let &cpo = s:save_cpo
  43. 43 unlet s:save_cpo

在vimscript中,通过exe命令可以执行vim本身的命令。

反正是调用API接口么,那么可以支持很多语言了。

比如可以通过:pe perl脚本的方式,直接执行perl语句。可以通过:help :perl查看:

  1. :pe[rl] {cmd} Execute Perl command {cmd}. The current package
  2. is "main".

Perl语言写vim插件例:

  1. function! WhitePearl()
  2. perl << EOF
  3. VIM::Msg("pearls are nice for necklaces");
  4. VIM::Msg("rubys for rings");
  5. VIM::Msg("pythons for bags");
  6. VIM::Msg("tcls????");
  7. EOF
  8. endfunction

常用的perl可调用接口有:

  1. :perl VIM::Msg("Text") # displays a message
  2. :perl VIM::Msg("Error", "ErrorMsg") # displays an error message
  3. :perl VIM::Msg("remark", "Comment") # displays a highlighted message
  4. :perl VIM::SetOption("ai") # sets a vim option
  5. :perl $nbuf = VIM::Buffers() # returns the number of buffers
  6. :perl @buflist = VIM::Buffers() # returns array of all buffers
  7. :perl $mybuf = (VIM::Buffers('qq.c'))[0] # returns buffer object for 'qq.c'
  8. :perl @winlist = VIM::Windows() # returns array of all windows
  9. :perl $nwin = VIM::Windows() # returns the number of windows
  10. :perl ($success, $v) = VIM::Eval('&path') # $v: option 'path', $success: 1
  11. :perl ($success, $v) = VIM::Eval('&xyz') # $v: '' and $success: 0
  12. :perl $v = VIM::Eval('expand("<cfile>")') # expands <cfile>
  13. :perl $curwin->SetHeight(10) # sets the window height
  14. :perl @pos = $curwin->Cursor() # returns (row, col) array
  15. :perl @pos = (10, 10)
  16. :perl $curwin->Cursor(@pos) # sets cursor to @pos
  17. :perl $curwin->Cursor(10,10) # sets cursor to row 10 col 10
  18. :perl $mybuf = $curwin->Buffer() # returns the buffer object for window
  19. :perl $curbuf->Name() # returns buffer name
  20. :perl $curbuf->Number() # returns buffer number
  21. :perl $curbuf->Count() # returns the number of lines
  22. :perl $l = $curbuf->Get(10) # returns line 10
  23. :perl @l = $curbuf->Get(1 .. 5) # returns lines 1 through 5
  24. :perl $curbuf->Delete(10) # deletes line 10
  25. :perl $curbuf->Delete(10, 20) # delete lines 10 through 20
  26. :perl $curbuf->Append(10, "Line") # appends a line
  27. :perl $curbuf->Append(10, "Line1", "Line2", "Line3") # appends 3 lines
  28. :perl @l = ("L1", "L2", "L3")
  29. :perl $curbuf->Append(10, @l) # appends L1, L2 and L3
  30. :perl $curbuf->Set(10, "Line") # replaces line 10
  31. :perl $curbuf->Set(10, "Line1", "Line2") # replaces lines 10 and 11
  32. :perl $curbuf->Set(10, @l) # replaces 3 lines

类似的,:py可以调用python语言,:rub可以使用ruby语言.

使用python的例子:

  1. :python from vim import *
  2. :python from string import upper
  3. :python current.line = upper(current.line)
  4. :python print "Hello"
  5. :python str = current.buffer[42]

Python调用vim命令的例子:

  1. :py print "Hello" # displays a message
  2. :py vim.command(cmd) # execute an Ex command
  3. :py w = vim.windows[n] # gets window "n"
  4. :py cw = vim.current.window # gets the current window
  5. :py b = vim.buffers[n] # gets buffer "n"
  6. :py cb = vim.current.buffer # gets the current buffer
  7. :py w.height = lines # sets the window height
  8. :py w.cursor = (row, col) # sets the window cursor position
  9. :py pos = w.cursor # gets a tuple (row, col)
  10. :py name = b.name # gets the buffer file name
  11. :py line = b[n] # gets a line from the buffer
  12. :py lines = b[n:m] # gets a list of lines
  13. :py num = len(b) # gets the number of lines
  14. :py b[n] = str # sets a line in the buffer
  15. :py b[n:m] = [str1, str2, str3] # sets a number of lines at once
  16. :py del b[n] # deletes a line
  17. :py del b[n:m] # deletes a number of lines

调用python文件,可以通过:pyfile或:pyf命令调用。

Ruby语言写vim插件的例子:

  1. function! RedGem()
  2. ruby << EOF
  3. class Garnet
  4. def initialize(s)
  5. @buffer = VIM::Buffer.current
  6. vimputs(s)
  7. end
  8. def vimputs(s)
  9. @buffer.append(@buffer.count,s)
  10. end
  11. end
  12. gem = Garnet.new("pretty")
  13. EOF
  14. endfunction

Ruby调用vim接口的示例:

  1. print "Hello" # displays a message
  2. VIM.command(cmd) # execute an Ex command
  3. num = VIM::Window.count # gets the number of windows
  4. w = VIM::Window[n] # gets window "n"
  5. cw = VIM::Window.current # gets the current window
  6. num = VIM::Buffer.count # gets the number of buffers
  7. b = VIM::Buffer[n] # gets buffer "n"
  8. cb = VIM::Buffer.current # gets the current buffer
  9. w.height = lines # sets the window height
  10. w.cursor = [row, col] # sets the window cursor position
  11. pos = w.cursor # gets an array [row, col]
  12. name = b.name # gets the buffer file name
  13. line = b[n] # gets a line from the buffer
  14. num = b.count # gets the number of lines
  15. b[n] = str # sets a line in the buffer
  16. b.delete(n) # deletes a line
  17. b.append(n, str) # appends a line after n
  18. line = VIM::Buffer.current.line # gets the current line
  19. num = VIM::Buffer.current.line_number # gets the current line number
  20. VIM::Buffer.current.line = "test" # sets the current line number

再来一个lua语言的:

  1. function! CurrentLineInfo()
  2. lua << EOF
  3. local linenr = vim.window().line
  4. local curline = vim.buffer()[linenr]
  5. print(string.format("Current line [%d] has %d chars",
  6. linenr, #curline))
  7. EOF
  8. endfunction

tcl语言的:

  1. function! DefineDate()
  2. tcl << EOF
  3. proc date {} {
  4. return [clock format [clock seconds]]
  5. }
  6. EOF
  7. endfunction

Atom的扩展

Atom的扩展的主力语言是CoffeeScript。

  1. YourNameWordCountView = require './your-name-word-count-view'
  2. {CompositeDisposable} = require 'atom'
  3. module.exports = YourNameWordCount =
  4. yourNameWordCountView: null
  5. modalPanel: null
  6. subscriptions: null
  7. activate: (state) ->
  8. @yourNameWordCountView = new YourNameWordCountView(state.yourNameWordCountViewState)
  9. @modalPanel = atom.workspace.addModalPanel(item: @yourNameWordCountView.getElement(), visible: false)
  10. # Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
  11. @subscriptions = new CompositeDisposable
  12. # Register command that toggles this view
  13. @subscriptions.add atom.commands.add 'atom-workspace',
  14. 'your-name-word-count:toggle': => @toggle()
  15. deactivate: ->
  16. @modalPanel.destroy()
  17. @subscriptions.dispose()
  18. @wordcountView.destroy()
  19. serialize: ->
  20. yourNameWordCountViewState: @yourNameWordCountView.serialize()
  21. toggle: ->
  22. console.log 'YourNameWordCount was toggled!'
  23. if @modalPanel.isVisible()
  24. @modalPanel.hide()
  25. else
  26. @modalPanel.show()

Visual Studio Code的扩展

Visual Studio Code的插件可以用JavaScript或者TypeScript来开发。

下面是个空的TypeScript的例子:

  1. // The module 'vscode' contains the VS Code extensibility API
  2. // Import the module and reference it with the alias vscode in your code below
  3. import * as vscode from 'vscode';
  4. // this method is called when your extension is activated
  5. // your extension is activated the very first time the command is executed
  6. export function activate(context: vscode.ExtensionContext) {
  7. // Use the console to output diagnostic information (console.log) and errors (console.error)
  8. // This line of code will only be executed once when your extension is activated
  9. console.log('Congratulations, your extension "my-first-extension" is now active!');
  10. // The command has been defined in the package.json file
  11. // Now provide the implementation of the command with registerCommand
  12. // The commandId parameter must match the command field in package.json
  13. var disposable = vscode.commands.registerCommand('extension.sayHello', () => {
  14. // The code you place here will be executed every time your command is executed
  15. // Display a message box to the user
  16. vscode.window.showInformationMessage('Hello World!');
  17. });
  18. context.subscriptions.push(disposable);
  19. }

Sublime Text的扩展

Sublime Text的扩展是用Python写的,举个处理回车换行的例子:

  1. def normalize_line_endings(self, string):
  2. string = string.replace('\r\n', '\n').replace('\r', '\n')
  3. line_endings = self.view.settings().get('default_line_ending')
  4. if line_endings == 'windows':
  5. string = string.replace('\n', '\r\n')
  6. elif line_endings == 'mac':
  7. string = string.replace('\n', '\r')
  8. return string

emacs的扩展

Emacs与以上的编辑器的最大不同的就是,无所谓扩展了,哪块看不顺眼就直接改了就是了。反正大部分都是绑定到快捷键上的函数而己。

比如,学习emacs的教程中,最开始讲的函数就是find-file,它的作用是打开文件,绑定在C-x C-f键上。水木社区官方QQ群进群问题就是问C-x C-f的作用是什么。

Emacs的好处是没有秘密,我们直接看源码,看看它是做啥的:

  1. (defun find-file (filename &optional wildcards)
  2. ... ;文档略
  3. (interactive
  4. (find-file-read-args "Find file: "
  5. (confirm-nonexistent-file-or-buffer)))
  6. (let ((value (find-file-noselect filename nil nil wildcards)))
  7. (if (listp value)
  8. (mapcar 'switch-to-buffer (nreverse value))
  9. (switch-to-buffer value))))

这么基础的命令,在其它编辑器中,一般没人改吧。但是在spacemacs中,C-x C-f就默认绑定ido-find-file函数上了。

  1. (defun ido-find-file ()
  2. (interactive)
  3. (ido-file-internal ido-default-file-method))

ido是Emacs的一个插件,意思是『Interactive Do』,在交互式操作方式上对基础的Emacs功能上有所增强。

即使在相对古老的emacs 23.x版本上,ido插件也是官方发布版本中的一部分。只不过官方版本上的键绑定还是绑到基础命令上。我们可以选择绑一个键给它,也可以通过Alt-x来运行它。

后面学习emacs的功能的时候,我们都会讲,标准emacs是如何做的,spacemancs是如何做的。大家可以看到,有很多标准emacs绑定的快捷键,在spacemacs上根本就不灵了,被绑定到别的功能上了。

所以,与其记快捷键,不如记函数名吧。也不用太精确,输的时候能找到就行。查帮助时会提升它绑到哪个键上,或者记不住就自己绑一个喜欢的也可以。

在Emacs中查找帮助

个人觉得,Emacs的文档确实不如Vim的文档写得好。但是,Emacs的文档也仍然是非常丰富的,实在查不到,咱还可以直接看代码。

官网上的文档

官网上的文档还是相当丰富的:https://www.gnu.org/software/emacs/manual/

除了基本功能外,常用的大插件的文档也不少,比如我用emacs写代码比较多,经常用cc-mode,cc-mode的文档也很详细:https://www.gnu.org/software/emacs/manual/html_node/ccmode/index.html

在emacs中查找帮助

既然我们已经了解到emacs就是一堆函数的组合,那么提供帮助功能,肯定也是调用相应的函数了。没错,正是这样!

如果想完整地阅读手册,可以调用info函数,默认绑定在C-h i组合上。

如果看到手册或者书上有讲一个快捷键是做什么的,我们可以查找它所对应的函数。查找一个按键的定义:C-h k (describe-key):比如我们就可以查查C-h k对应的功能:

  1. C-h k runs the command describe-key, which is an interactive compiled
  2. Lisp function.
  3. It is bound to C-h k, <f1> k, <help> k, <menu-bar> <help-menu>
  4. <describe> <describe-key-1>.
  5. (describe-key &optional KEY UNTRANSLATED UP-EVENT)
  6. Display documentation of the function invoked by KEY.
  7. KEY can be any kind of a key sequence; it can include keyboard events,
  8. mouse events, and/or menu events. When calling from a program,
  9. pass KEY as a string or a vector.
  10. If non-nil, UNTRANSLATED is a vector of the corresponding untranslated events.
  11. It can also be a number, in which case the untranslated events from
  12. the last key sequence entered are used.
  13. UP-EVENT is the up-event that was discarded by reading KEY, or nil.
  14. If KEY is a menu item or a tool-bar button that is disabled, this command
  15. temporarily enables it to allow getting help on disabled items and buttons.

从帮助中我们可以看到,快捷键绑到C-h k,而实际调用的函数是describe-key.

同样,我们还可以通过C-h f (describe-function)来查询一个函数的功能。

  1. describe-function is an interactive compiled Lisp function.
  2. It is bound to C-h f, <f1> f, <help> f, <menu-bar> <help-menu>
  3. <describe> <describe-function>.
  4. (describe-function FUNCTION)
  5. Display the full documentation of FUNCTION (a symbol).

另外,还有查询变量的describe-variable函数,绑定到C-h v键上。

小结

  1. emacs的基本用法,就是调用一些函数而己。这些函数可以通过Alt-x加上函数名去调用。
  2. 常用函数可以绑定到一些快捷键上。很多emacs入门教程讲的就是这些功能的用法
  3. info用于在emacs中查看手册, describe-funciton查找函数用法,对于lisp函数经常可以直达源码。describe-key查找键值绑定。它们默认的绑定是C-h i, C-h f和C-h k。在以后的emacs岁月里,您会经常用到它们的

我也说说Emacs吧(2) - Emacs其实就是函数的组合的更多相关文章

  1. 我也说说Emacs吧(1) - Emacs和Vi我们都学

    好友幻神的<Emacs之魂>正在火热连载中,群里人起哄要给他捧捧场. 作为一个学习Emacs屡败屡战的用户,这个场还是值得捧一下的.至少我是买了HHKB键盘的... 从我的键盘说起 - 有 ...

  2. emacs使用本地emacs server模式打开远程文件

    使用emacs的用户都知道,一般要打开远程机器上的文件要使用TrampMode模式,调用方式例如以下: C-x C-f /remotehost:filename RET (or /method:use ...

  3. [daily][emacs][go] 配置emacs go-mode的编辑环境以及环境变量问题

    1. 安装go 安装go-mode 使用emacs编辑go代码的时候,你需要有正常可运行的go环境. 并且有emacs的go-mode package https://www.emacswiki.or ...

  4. emacs编译整个emacs.d目录

    $emacs 在emacs查看里面,输入: C-u M-x byte-recompile-directory 然后输入 ~/.emacs.d 即可.

  5. Emacs 配置文件

    以下是我整理的 emacs 配置文件,供刚开始玩 emacs 的同学参考.网上有人说:emacs 是神的编辑器,如果能够用到这样的编辑器,那这个人就是神了.从我个人的经验来看,emacs 是一把利器, ...

  6. 创建.emacs.d目录和.emacs文件

    1.双击bin下的addpm.exe 2.HKEY_CURRENT_USER->Software->GNU->Emacs 新建字符串值HOME,数值数据为emacs的安装路径 3.创 ...

  7. 打造最高效的科研环境之Emacs插件们

    0 盲人摸象 作为初学者,迫切的需求就是直接上手Emacs并打造包含自动补全命令在内的科研环境. 和网上众多的插件安装的教程相比,我认为找到一个与自己需求匹配的Emacs配置环境来得更方便. 本例中, ...

  8. CentOS 6.7 中安装Emacs 24.5

    Emacs 版本:http://mirror.bjtu.edu.cn/gnu/emacs/emacs-24.5.tar.gz CentOS 内核版本:2.6.32-573.el6.x86_64 参考资 ...

  9. windows8.1下常用编辑器安装配置(emacs/vim/sublime text3)

    一.下载:在emacs:http://mirrors.ustc.edu.cn/gnu/emacs/windows/里下载emacs-24.3-bin-i386.zip.解压到自定目录,双击bin文件夹 ...

随机推荐

  1. python爬虫之新浪微博登录

    fiddler 之前了解了一些常见到的反爬措施,JS加密算是比较困难,而微博的登录中正是用JS加密来反爬,今天来了解一下. 分析过程 首先我们去抓包,从登录到微博首页加载出来的过程.我们重点关注一下登 ...

  2. eclipse集成tomcat修改字符集参数

    问题: 在eclipse 4.4(Luna)中集成tomcat时,直接修改原tomcat目录中的配置文件,不起作用. 有时,我们会修改字符集参数为utf-8,以解决中文乱码问题,改动之后依然乱码…… ...

  3. Commons之Commons-io

    转载自(https://my.oschina.net/u/2000201/blog/480071) 1  概述 Commons IO是针对开发IO流功能的工具类库. 主要包括六个区域: 工具类——使用 ...

  4. 解析TCP三次握手

    转自:http://www.jellythink.com/archives/705 三次握手又是什么? TCP是面向连接的,无论哪一方向另一方发送数据之前,都必须先在双方之间建立一条连接.在TCP/I ...

  5. Sublime使用记录之SublimeServer插件介绍

    Sublime使用记录之SublimeServer插件介绍 介绍:sublimeServer

  6. 2017 ACM/ICPC Asia Regional Shenyang Online array array array

    2017-09-15 21:05:41 writer:pprp 给出一个序列问能否去掉k的数之后使得整个序列不是递增也不是递减的 先求出LIS,然后倒序求出最长递减子序列长度,然后判断去k的数后长度是 ...

  7. 如何利用mixin编写media query的代码

    mixins允许文档作者定义的属性对时可以在其他规则集中重用的模式. Media Queries直译就是“媒体查询”.media就是来指定特定的媒体类型,如屏幕(screen),或者“TV”等,其中“ ...

  8. LightOJ 1341 Aladdin and the Flying Carpet(唯一分解定理)

    http://lightoj.com/volume_showproblem.php?problem=1341 题意:给你矩形的面积(矩形的边长都是正整数),让你求最小的边大于等于b的矩形的个数. 思路 ...

  9. Class 的继承

    简介 Class 可以通过extends关键字实现继承,这比 ES5 的通过修改原型链实现继承,要清晰和方便很多. class Point { } class ColorPoint extends P ...

  10. 英语每日阅读---8、VOA慢速英语(翻译+字幕+讲解):脸肓症患者记不住别人的脸

    英语每日阅读---8.VOA慢速英语(翻译+字幕+讲解):脸肓症患者记不住别人的脸 一.总结 一句话总结: a.neural abnormalities are more widespread:Duc ...