Planet Emacs CN

August 21, 2018

最新版magit-blame不显示commit id

@lemon0910写道:

最新版magit-blame不显示commit id,只显示提交者,时间和message信息,有人知道怎么设置显示commit-id信息吗

帖子: 2

参与者: 2

阅读整个主题

by @lemon0910 lemon0910 at August 21, 2018 08:42 AM

spacemacs font-lock+ 安装失败

@yicao写道:

An error occurred while installing font-lock+ 有遇到过的吗

帖子: 3

参与者: 3

阅读整个主题

by @yicao yicao at August 21, 2018 12:31 AM

August 20, 2018

强烈推荐一个笔记应用:Notebook!

@casouri写道:

https://www.zoho.com/notebook/evernote-alternative.html

完爆evernote的地方:

  1. 免费
  2. 更强的web clipper
  3. 美丽的界面
  4. 对触控操作的支持很好,evernote只能点点点,Notebook支持很多有用的滑动操作

不输evernote的地方:

  1. ZOHO算是个大企业,不会随便停止维护更新(evernote的维护更新也就……)
  2. 电脑,移动端都支持
  3. 笔记整理功能

获取方式:

(macOS/iOS)App Store 搜索 “Notebook”。 这个图标:54%20AM

特意找的油管视频:

https://www.youtube.com/watch?v=yyHPiBroUpI

帖子: 3

参与者: 2

阅读整个主题

by @casouri Yuan Fu at August 20, 2018 01:34 PM

请问spacemacs python layer支持类似pycharm的缩进参考线吗?

by @aladdinwang Wang, Enjun at August 20, 2018 10:49 AM

August 19, 2018

emacs 修改文件提示没有权限

@baker写道:

emacs在修改/etc/*** 文件时候,没有权限,无法写入。

帖子: 9

参与者: 4

阅读整个主题

by @baker baker at August 19, 2018 02:00 PM

clang无法补全c++函数,但是c函数可以

@pzh2386034写道:

pans-MacBook-Pro:oj pan$ clang --version clang version 6.0.1 (tags/RELEASE_601/final) Target: x86_64-apple-darwin17.4.0 Thread model: posix InstalledDir: /usr/local/opt/llvm/bin

ProductName: Mac OS X ProductVersion: 10.13.3 BuildVersion: 17D47

GNU Emacs 25.3.1

c++函数就不行

c函数补全是ok的

大家帮忙看下怎么才能搞定。。新手。。

clang-err报错信息:

/usr/local/opt/llvm/bin/clang -fsyntax-only -Xclang -code-completion-macros -x c++ -I/usr/include/sys/ -Xclang -code-completion-at=-:26:17 -

In file included from :1: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/iostream:38: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/ios:215: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/iosfwd:90: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/wchar.h:119: In file included from /usr/include/wchar.h:92: In file included from /usr/include/_wctype.h:42: In file included from /usr/include/__wctype.h:62: /usr/include/_types/_wctype_t.h:32:9: error: unknown type name ‘__darwin_wctype_t’ typedef __darwin_wctype_t wctype_t; ^ In file included from :1: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/iostream:38: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/ios:215: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/iosfwd:90: In file included from /usr/local/Cellar/llvm/6.0.1/include/c++/v1/wchar.h:119: /usr/include/wchar.h:98:15: error: unknown type name ‘FILE’ wint_t fgetwc(FILE *); ^ /usr/include/wchar.h:99:44: error: unknown type name ‘FILE’ wchar_t *fgetws(wchar_t * __restrict, int, FILE * __restrict); ^ /usr/include/wchar.h💯24: error: unknown type name ‘FILE’ wint_t fputwc(wchar_t, FILE *); ^ /usr/include/wchar.h:101:40: error: unknown type name ‘FILE’ int fputws(const wchar_t * __restrict, FILE * __restrict); ^ /usr/include/wchar.h:102:11: error: unknown type name ‘FILE’ int fwide(FILE *, int); ^ /usr/include/wchar.h:103:14: error: unknown type name ‘FILE’ int fwprintf(FILE * __restrict, const wchar_t * __restrict, …); ^ /usr/include/wchar.h:104:13: error: unknown type name ‘FILE’ int fwscanf(FILE * __restrict, const wchar_t * __restrict, …); ^ /usr/include/wchar.h:105:14: error: unknown type name ‘FILE’ wint_t getwc(FILE *); ^ /usr/include/wchar.h:113:23: error: unknown type name ‘FILE’ wint_t putwc(wchar_t, FILE *); ^ /usr/include/wchar.h:117:24: error: unknown type name ‘FILE’ wint_t ungetwc(wint_t, FILE *);

帖子: 3

参与者: 2

阅读整个主题

by @pzh2386034 Pzh2386034 at August 19, 2018 12:48 PM

emacs怎么配置c++注释风格

@creatorlxd写道:

我刚使用emacs,在自己改了cc-mode后不知道如何调在c++中的注释风格。就比如我想使用如下的风格:

/*
some thing
*/

但是emacs下默认出来的是这样的:

/*
 *
 */

cc-mode的文档太长,我英语不好,看的不是很明白,希望有哪位大佬能帮帮我。谢了。

帖子: 3

参与者: 3

阅读整个主题

by @creatorlxd at August 19, 2018 06:55 AM

无论是 ParEdit 还是 Smartparens 都很难用啊

@Roife写道:

尝试了这两款括号插件,各自都有着不同方面的遗憾。

ParEdit 在 Lisp-like 的语言下很好用,但是到了 C++ 之类的语言就难用无比。

  1. 输入括号会自动在括号前面加一个空格。在 Lisp 中这个特性很好,然而在 C++ 中简直是灾难
  2. paredit-semicolon 这个函数只针对分号有效,然而一般来说用“//”作为注释,所以只能把这个东西禁用掉

Smartparens 在某一些方面(比如对于其他mode的支持上)比 ParEdit 做得更好,然而实际用起来还不如 ParEdit

  1. 始终没有找到在c++ -mode中开启 strict-mode 的措施
  2. 在字符串中也会匹配括号

帖子: 8

参与者: 7

阅读整个主题

by @Roife Roife at August 19, 2018 04:25 AM

August 18, 2018

COSMAC ELF:70年代用开关编程的个人电脑

@LdBeth写道:

image

虽然得通过键盘或开关直接把程序输入内存,最多只支持 64kb 内存,但这是货真价实的个人电脑,可以通过 Driect memory access 显示图形,可以通过在 Q 针脚接放大器发出声音,可以通过 VT-100 终端交互,可以运行 BASIC,FORTH,LISP,可以运行一个带有文本编辑器汇和编器,具有文件系统的磁盘操作系统。

现在这款型号的处理器仍在被生产,主要用于包括哈勃望远镜在内的航天器。

Windows, Unix 版本的模拟器以及上述提到的程序:http://www.elf-emulation.com/emulator.html

OS X 版本的模拟器以及编程指南:http://www.tinyelf.com/

COSMAC ELF 主页:http://www.cosmacelf.com/

它的汇编语言相当简单易学,也可作为了解计算机如何运行的教学。

帖子: 3

参与者: 2

阅读整个主题

by @LdBeth 好船 at August 18, 2018 04:00 PM

终于打通任督二脉! 把org日程显示在i3blocks上的脚本

@guo写道:

这个脚本的一些参数是按我自己的需要显示的, 需要的可以自己改里面的参数.

下面这个脚本的功能:

  1. 没有3天内的任务时,显示"NOTHING TODO

  2. 3天内到期的任务用红色显示.

  3. 当不止一个任务时自动轮询任务.时间间隔由i3blocks的刷新间隔控制.

     #!/bin/bash
     [ ! -f /tmp/todo ] && echo 0 > /tmp/todo
     n=$(cat /tmp/todo)
     n=$(expr $n + 1)
     echo $n > /tmp/todo
     todo=$(emacs \
                --batch\
                --user\
                $USER\
                --eval "(progn (org-agenda-list nil nil 'week) (write-file \"/dev/stdout\"))" \
                2> /dev/null\
                | grep "^ .*"\
                | grep -v "Deadline"\
         )
     lines=$(echo "$todo" | sed '/^$/d' | wc -l)
     if [[ 0 -eq $lines ]]; then
         echo "NOTHING TODO"
         echo
         echo \#00FFFF
         exit
     fi
     if [[ $n -gt $lines ]]; then
         n=1
         echo 0 > /tmp/todo
     fi
     text=$(echo "$todo" | head -n $n | tail -n 1)
     text=$(echo "$text" | sed 's/.*my-todo: *//')
     days=$(echo "$text" | sed 's/.*In *\(.*\)\s *d.*/\1/')
     text=$(echo "$text" | sed 's/.*TODO \(.*\)/\1/')
     echo "[$n/$lines] ${days}d $text"
     echo
     if [[ $days -le 3 ]]; then
         echo \#FF0000
     else
         echo \#00FFFF
     fi

帖子: 1

参与者: 1

阅读整个主题

by @guo 老锅 at August 18, 2018 12:54 PM

如何让 Paredit 与 Hungry-delete 一起工作

@Roife写道:

我在配置中使用了 paredit-mode,所以把delete键也绑定到了“(paredit-backward-delete)”。但是这样一来 hungry-delete 便不工作了。有什么解决办法吗?

帖子: 2

参与者: 2

阅读整个主题

by @Roife Roife at August 18, 2018 06:09 AM

如何在 eww 中登陆账号?

@Roife写道:

不能登录总还是有很多操作无法进行

帖子: 2

参与者: 2

阅读整个主题

by @Roife Roife at August 18, 2018 02:14 AM

August 17, 2018

emacs-devel 上关于 JIT Compiler 的讨论

@yyjjl写道:

有人已经给 elisp 加 JIT Compiler 了 https://lists.gnu.org/archive/html/emacs-devel/2018-08/msg00393.html

emacs-mirror 上新的 branch features/libjit

帖子: 11

参与者: 8

阅读整个主题

by @yyjjl yyj at August 17, 2018 02:38 AM

August 16, 2018

pyim 和 pyim-cangjie5dict

@nZaegik写道:

我猜問題就是我不知道怎麼配置 pyim-cangjie5dict。有人成功嗎? 下面是我的code.

(use-package pyim

:ensure t

:config

(use-package pyim-cangjie5dict

:ensure t

:config (pyim-cangjie5dict-enable)))

(setq default-input-method “pyim”)

(setq pyim-default-scheme 'cangjie)

我把它enable的時候 (:config (pyim-cangjie5dict-enable)﹐它會說「Symbol’s function definition is void: pyim-cangjie5dict-enable」。 如果沒有enable它﹐直接使用pyim﹐它會打英文字母﹐不是打倉頡碼﹐但是下面也有「灵通」這兩個字﹐表示pyim成功裝了。有人知道什麼問題嗎?我用pyim普通打拼音的話沒問題﹐只是倉頡。 還有﹐不好意思我中文不太好﹐我是海外華人。

帖子: 4

参与者: 3

阅读整个主题

by @nZaegik 亞諾 at August 16, 2018 10:37 PM

Lady luck is smilin’.

test

August 16, 2018 06:04 PM

Spacemacs keybindings

This is my Spacemacs personal config on Github: https://github.com/ztlevi/spacemacs-config

> Common Stuffs

In key bindings, M stands for Alt key (option key for mac), s for Command key, C for Control key, SPC for Space key.

Key BindingsDescription
C-gQuit
! !evil shell command output to the current line
C-oEvil jump backward
C-iEvil jump forward
C-oOpen Action panel when mini dired enabled
C-h k/v/f/dKey/ variable/ function/ Documentation
C-h C-k/v/fFind key/ variable/ function
C-h eShow Emacs’s errors
SPC SPC (M-x)eval-buffer, customize-group
SPC e nJs2-next-error
s-/Comment
SPC j iImenu (show all the functions)
SPC vExpand Region
SPC x oOpen link
C-qInsert Quote
SPC s eiedit: need to select in vim-visual mode, and then press the key to edit them.
SPC ?List key bindings
*SPC '*Pop up shell

> Debug

Kill emacs when not responding: pkill -SIGUSR2 -i emacs, and use toggle-debug-on-quit to enable C-g.

The following command profile the CPU.

Profiler-startProfiler-report
Key BindingsDescription
C-x C-eeval-last-sexp
M-.pop last command execute
Diminish UndoShow mode detail in the mode line, e.g. company-mode
SPC o (Switches to the buffer ‘*ielm*’, or creates it if it does not exist.
*, d m*macrostep-transient-state, expand and collapse funcs and macros

> Python

In python mode, keys are start with prefix key C-c.

Key BindingsDescription
C-c C-prun python
C-c C-cpython shell send buffer
C-c C-lpython shell send file
C-c C-rpython shell send region
C-c C-zpython shell switch to shell

Key BindingsDescription
SPC o d (M-s o)Occur dwim (see the occurrences in codes and
go through them by toggling them), use e to enter edit
eGo to edit mode (Under Occur mode)
C-c C-cExit edit mode (Under Occur mode)
C-sSwiper
SPC r i / C-c C-r (F6)Ivy-resume, e.g. resume the swiper view
SPC r hHelm-resume, e.g. resume counsel-git view
SPC sGrep(g), ag(a), ack(k), pt(t) <br>Project a/g p, Directory t/k f.
C-c C-eShow results in another buffer, and then edit(e.g. replace).
C-c C-cOn the result buffer, commit changes.

> Replace

  1. Just use vim, :%s/xxx/yyy/g(c)
  2. Mark a key word, then use C-r (evil-quick-replace). It will automatically generate the vim command.
  3. Use Occur-dwim (SPC o d), then use iedit (SPC s e).
Key BindingsDescription
M-%query-replace
C-M-%query-replace-regexp

> Toggle

Key BindingsDescription
Spc t nToggle line number
Spc t rToggle relative line number
SPC t gtoggle golden ration
SPC t -Center point
SPC t fToggle fci-mode
Key BindingsDescription
Spc h bOpen bookmarks in helm window
C-ddelete the selected bookmark
C-eedit the selected bookmark
C-ftoggle filename location
C-oopen the selected bookmark in another window
C-x C-dRun browse project directory
SPC fFile related operation
SPC p fOpen file with projectile or counsel-git
SPC f fHelm-find-file
C-M-jIvy immediate done
SPC f LFind the file across the Whole Mac System
SPC f lfind file literally
SPC f hOpen file in hex mode(C-c C-c to exit)
SPC f oOpen in default external application
SPC f Esudo edit
SPC f jJump to dried, remapped to ranger
SPC f rOpen recent file
SPC f RRename current file
SPC f vAdd local variable
SPC f a dfind the current visited directory with fasd
SPC f C d/uconvert file encoding between unix and dos
SPC f e dfind the .spacemacs file
SPC f e ifile the .emacs init file
SPC f bShow bookmarks
SPC f s/SSave buffers
SPC f cCopy file
SPC f tOpen neo tree
SPC bBuffer related operation
SPC TABSwitch back and forth
SPC b .buffer micro state (hydra)
SPC b bSwitch buffers
SPC b dKill buffer
SPC b fReveal in finder
SPC b B/iiBuffer
SPC b hSpacemacs home buffer
SPC b kKill matching buffers
SPC b NNew empty buffer
SPC b C-dKill other buffers
SPC b RSafe revert buffer
SPC b sScratch buffer
SPC b YYank the whole buffer
SPC b PPaste the whole buffer
SPC b wWrite in dried buffer
SPC b n/pNext/Previous buffer
SPC lLayout related operation
SPC o l lload layout (ztlevi)
SPC o l ssave layout (ztlevi)
SPC l oCustom layout
SPC l L/sLoad or Save layout
SPC l lSwitch between layouts
SPC l RRename current layout
SPC l TABQuick switch between layouts
SPC l ?Toggle layout help
SPC wWindow Related Operation
SPC w .Window micro state (cheat sheet)
SPC w -/sSplit window below and focus
SPC w //vSplit window right and focus
SPC w mToggle-maximize-buffer
SPC w 2/3Use predefined window layout
SPC w bSwitch to mini buffer
SPC w dDelete the current window
SPC w h/j/k/lMove to window
SPC w mMaximize window
SPC w H/J/K/LMove window to position
SPC w u/UWindow undo/redo
SPC w oSwitch to other frame
SPC w Fmake a new frame
M/(SPC w) 1/2/3/4Go to window with the window number
SPC w =Balance windows
SPC w wGo to other window one by one
SPC w WAce windows
SPC pProject related operation
SPC p fProject files
SPC p bBuffer files
SPC p pSwitch to a project
SPC p lSwitch to a project and create a layout
s-pFind files in project
SPC f jDired Related Operation
j(dired) navigate down
k(dired) navigate up
h(dired) go up directory
l(dired) find file / enter directory
mMark files. Use it with C and R
uUnmark files. Use it with C and R
tMark all files.
UUnmark all files.
CWhen you will press C to copy, the other dir in the split pane will be default destination.
RSame thing with C. R stands for rename but also does move
fFind file. Can be used to create file.
+Create directory
oOpen file in another window
dMark as delete.
xTake the punge.
SPC aRanger Related Operation
C-c C-eWdired-change-to-wdired-mode: write in ranger
C-c C-cCommit changes
C-c EscAbort changes
SPC a rlaunch ranger
SPC a ddeer (minimal ranger window in current directory)
C-p(ranger) toggle ranger in dired buffer
j(ranger) navigate down
k(ranger) navigate up
h(ranger) go up directory
l(ranger) find file / enter directory
RET(ranger) find file / enter directory
dd/ da(ranger) cut, da to add cut file
yy/ ya(ranger) copy, ya to add copy file
pp(ranger) paste
R(ranger) rename
D(ranger) delete
;+(ranger) create directory
f(ranger) search for file names, also can create file
i(ranger) show preview of current file
zi(ranger) toggle showing literal / full-text previews
zh(ranger) toggle showing dotfiles
o(ranger) sort options
H(ranger) search through history
q(ranger) quit
r(ranger) revert buffer
z-(ranger) reduce number of parents
z+(ranger) increment number of parents
v(ranger) toggle all marks
V(ranger) visually select lines
S(ranger) enter shell
C-SPC(ranger) mark current file
;C(ranger) copy directory / copy and move directory

> Org mode

Key BindingsDescription
SPC a o o (C-c a)Org agenda
SPC m s (C-c C-s)Schedule
SPC m d (C-c C-d)Deadline
C-c C-eOrg Export
C-c C-cOrg evaluate block
  • Org evaluate block example:
#+BEGIN_SRC python :results output
for i in range(10):
print(i)
#+END_SRC

> Cycling

  1. Tab: toggle current headline
  2. S-Tab: globally toggle headlines

> Headline movement

Key BindingsDescription
C-Insert heading respect current content below
M-/lDemote heading, list item at point or move table column right.
M-/hPromote heading, list item at point or move table column left.
M-/kMove subtree or table row up
M-/jMove subtree or table row down

> JS2 Mode

Key BindingsDescription
js2-refactor commandsA lot more key bindings could be found here
, r <js2r-forward-braf
, r >js2r-forward-slurp
The following 3 commands using xref-js2
M-.Jump to definition
M-,Pop back to where M-. was last invoked.
M-?Jump to references

August 16, 2018 06:04 PM

With 1% effort to build 99% working Hackintosh

This is my 2017 Hackintosh build. I was using GTX 970 before but I just switch to Vega 64 recently. And it works out of box!!! That’s the key to the whole build. With Vega GPU, you don’t have to worry about tricky bugs any more. We just need to set up a clean build.

> Parts list

> Building

For the build, the liquid cooler cannot fit in the top of the case with this special motherboard. I remove the front fan and put it at the top of the case. Then I install the liquid cooler up front the case.

> Installation

I just follow the installation from Tonymacx86 High Sierra Installation and that’s works for me.

The SMBIOS setting I’m using is iMac 14,2. I was using iMac 18,3 before but once I switch to Vega graphics card, it will cause black screen. So I suggest to stick with 14,2.

The only issue I have is the audio. I am not sure it’s the macOS version 10.13.4’s problem or Vega graphics card’s. A quick fix is using USB to headphone jack converter. You can buy anyone from Amazon.

In 90% cases, you can go ahead update your system without any problem. But be careful, and check out Tonymacx86’s update posts. For example, you might have to update your clover bootloader or replace your old apfs.efi to the new one.

August 16, 2018 06:04 PM

Java: you do not know Ⅱ

> Treemap, HashMap, LinkedHashMap

Q: Explain the differences between TreeMap, HashMap, and LinkedHashMap. Provide an example of when each one would be best.

A: The most important distinction between these classes is the time guarantees and the ordering of the keys.

  • HashMap offers O(1) lookup and insertion. If you iterate through the keys, though, the ordering of the keys is essentially arbitrary. It is implemented by an array of linked lists.
  • TreeMap offers P(logN) lookup and insertion. Keys are ordered, so if you need to iterate through the keys in sorted order, you can. This means that keys must implement the Comparable interface. TreeMap is implemented by a Red-Black Tree.
  • LinkedHashMap offers O(1) lookup and insertion. Keys are ordered by their insertion order. It is implemented by doubly-linked buckets.

Q: What suppose to the key ordering with the input ordering {1, -1, 0}?

A:

HashMapLinkedHashMapTreeMap
any ordering{1, -1, 0}{-1, 0, 1}

Q: When might you need ordering in real life?

A:

  • Suppose you were creating a mapping of names to Person objects. You might want to periodically output the people in alphabetical order by name. A TreeMap lets you do this.
  • A TreeMap also offers a way to, given a name, output the next 10 people. This could be useful for a “More” function in many applications.
  • A LinkedHashMap is useful whenever you need the ordering of keys to match the ordering of insertion. This might be useful in a caching situation, when you want to delete the oldest item.

Generally, unless there is a reason not to, you would use HashMap.

> Object Reflection

Q: Explain what object reflection is in Java and why it is useful?

A: Object Reflection is a feature in Java that provides a way to get reflective information about Java classes and objects, and perform operations such as:

  1. Getting information about the methods and fields present inside the class at runtime.
  2. Creating a new instance of a class.
  3. Getting and setting the object fields directly by getting field reference, regardless of what the access modifier is.

> Lambda Expression

Q: There is a class Country that has methods getContinent() and getPopulation(). Write a function int getPopulation(List countries, String continent) that computes the total population of a given continent, given a list of all countries and the name of a continent.

A: This question really comes in two parts. First, We need to generate a list of the countries in North America. Then, we need to compute their total population.

Without lambda expression, this is fairly straightforward to do.

int getPopulation(List<Country> countries, String continent) {
int sum = 0;
for (Country c : countries) {
if (c.getContinent().equals(continent)) {
sum += c.getPopulation();
}
}
return sum;
}

To implement this with lambda expression, let’s break this up into multiple parts.

int getPopulation(List<Country> countries, String continent) {
/* Filter countries.*/
Stream<Country> northAmerica = countries.stream.filter(
country -> {return country.getContinent().equals(continent);}
);

/* Convert to list of populations.*/
Stream<Integer> populations = northAmerica.map(
c -> c.getPopulation()
);

/* Sum list.*/
int population = populations.reduce(0, (a, b) -> a + b);
return population;
}

Alternatively, the following code will disregard the countries no within continent according to the sum.

int getPopulation(List<Country> countries, String continent) {
Stream<Integer> populations = countries.stream().map(
c -> c.getPopulation().equals(continent) ? c.getPopulation() : 0
);

return populations.reduce(0, (a, b) -> a + b);
}

> Lambda Random

Q: Using Lambda expressions, write a function List get RandomSubset(List list) that returns a random subset of arbitrary size. All subsets (including the empty set) should be equally likely to be chosen.

A: To implement this approach using lambda expressions, we can do the following:

List<Integer> getRandomSubset(List<Integer> list) {
Random random = new Random();
List<integer> subset = list.stream().filter(
k -> {return random.nextBoolean(); // Flip coin
}).collect(Collectors.toList());
return subset;
}

August 16, 2018 06:04 PM

Spacemacs/Space-Vim Config for VSCode

> The space way

> Leader key

Using space key as the leader is a very popular way of editing, navigation and commanding. There is never an easy way to get used to new shortcuts, but trust me, you would definitely like it once you use it.

> Sticky key

Think about how you invoke commands in VSCode before. When you want to call the command-palette, you need to put your left hand’s two fingers on Ctrl + Shift key or Command + Shift key and press p. And note that it’s a key chord combination when you actually press these keys.

This looks so stupid when you compare it with just Space Space in Vim’s normal or visual mode. And by saying Space Space, it’s a sticky key bindings which means you just type space key twice in sequence. And you can just set your hands as the default typing position shown in this picture.

> Prefix key

Well, now you probably get the point of using space key. But there is more of it.

Since sticky keys are just key sequences, you can cluster a lot of similar commands to a prefix like space f(file related commands). For example, space f f go to the explorer, space f ssave file and space f Ssave all. In this case, you won’t mess up with these keys because they have the same prefix space f.

> The hybrid editing mode

> Insert mode

Spacemacs has a hybrid mode that takes the normal and visual modes’ key bindings from Vim while still using the general Emacs key bindings in insert mode. To be honest, it’s super smart way of editing.

The Unix key bindings (C-a->home, C-e->end, C-b->back, C-f->forward, C-n->next line, C-p->last line) work in almost every Mac application. You probably never find out they work out of box in your Mac or Linux, but many of your guys don’t know about it.

So, why the hell people want to use Unix key bindings in their machines?

There are many reasons:

  1. Your Mac does not has the home, end key like a full keyboard.
  2. It’s a much faster way for navigation once you get used to it
  3. Be more consistent about the key bindings. They work in terminal, intellij IDEA, even Wechat. So why not use it everywhere.

> Normal & visual mode

As for the normal and visual mode, They are pretty much the same. But they can do much more now in space way.

Note: The leader key is space

KeyDescription
leader spaceshow commands
leader b bquick open (see your opened files)
leader f fgo the explorer
leader f ssave file
leader f Ssave all
leader =beautify file
leader w [lhjk]navigate window
leader w vsplit vertically
C-g (Optional)ESC

> To use it

  1. Add the following configuration in your VSCode’s User Setting (You can find out how to get to the User Setting over here).
{
// Vim setting
"vim.useSystemClipboard": true,
"vim.easymotion": false,
"vim.easymotionMarkerFontFamily":
"Operator Mono Lig, Ubuntu Mono, Menlo, Monaco, 'Courier New', monospace",
"vim.easymotionMarkerFontSize": "14",
"vim.handleKeys": {
"<C-n>": false,
"<C-p>": false,
"<C-a>": false,
"<C-e>": false
},
"vim.leader": "<space>",
"vim.insertModeKeyBindings": [
{
"before": ["<C-f>"],
"after": ["<right>"]
},
{
"before": ["<C-b>"],
"after": ["<left>"]
},
{
"before": ["<C-e>"],
"commands": [
{
"command": "cursorEnd",
"when": "editorTextFocus"
}
]
},
{
"before": ["<C-a>"],
"commands": [
{
"command": "cursorHome",
"when": "editorTextFocus"
}
]
},
{
"before": ["<C-d>"],
"commands": [
{
"command": "deleteRight",
"when": "editorTextFocus && !editorReadonly"
}
]
}
],
"vim.normalModeKeyBindingsNonRecursive": [
{
"before": ["g", "r"],
"commands": [
{
"command": "editor.action.referenceSearch.trigger",
"when":
"editorHasReferenceProvider && editorTextFocus && !inReferenceSearchEditor && !isInEmbeddedEditor"
}
]
},
{
"before": ["<C-a>"],
"commands": [
{
"command": "cursorHome",
"when": "editorTextFocus"
}
]
},
{
"before": ["<C-e>"],
"commands": [
{
"command": "cursorEnd",
"when": "editorTextFocus"
}
]
},
{
"before": ["<C-k>"],
"after": ["D"]
},
{
"before": ["<leader>", "<space>"],
"after": [],
"commands": [
{
"command": "workbench.action.showCommands",
"args": []
}
]
},
{
"before": ["<leader>", "'"],
"after": [],
"commands": [
{
"command": "workbench.action.terminal.toggleTerminal",
"args": []
}
]
},
{
"before": ["<leader>", "1"],
"after": [],
"commands": [
{
"command": "workbench.action.focusFirstEditorGroup",
"args": []
}
]
},
{
"before": ["<leader>", "2"],
"after": [],
"commands": [
{
"command": "workbench.action.focusSecondEditorGroup",
"args": []
}
]
},
{
"before": ["<leader>", "3"],
"after": [],
"commands": [
{
"command": "workbench.action.focusThirdEditorGroup",
"args": []
}
]
},
{
"before": ["<leader>", "b", "b"],
"after": [],
"commands": [
{
"command": "workbench.action.quickOpen",
"args": []
}
]
},
{
"before": ["<CR>"],
"after": [],
"commands": [
{
"command": "workbench.action.quickOpen",
"args": []
}
]
},
{
"before": ["<leader>", "b", "d"],
"after": [],
"commands": [
{
"command": "workbench.action.closeActiveEditor",
"args": []
}
]
},
{
"before": ["<leader>", "b", "n"],
"after": [],
"commands": [
{
"command": "workbench.action.nextEditor",
"args": []
}
]
},
{
"before": ["<leader>", "b", "p"],
"after": [],
"commands": [
{
"command": "workbench.action.previousEditor",
"args": []
}
]
},
{
"before": ["<leader>", "e", "l"],
"after": [],
"commands": [
{
"command": "workbench.actions.view.problems",
"args": []
}
]
},
{
"before": ["<leader>", "f", "e"],
"after": [],
"commands": [
{
"command": "workbench.action.openGlobalSettings",
"args": []
}
]
},
{
"before": ["<leader>", "f", "f"],
"after": [],
"commands": [
{
"command": "workbench.action.files.openFile",
"args": []
}
]
},
{
"before": ["<leader>", "f", "r"],
"after": [],
"commands": [
{
"command": "workbench.action.openRecent",
"args": []
}
]
},
{
"before": ["<leader>", "f", "s"],
"after": [],
"commands": [
{
"command": "workbench.action.files.save",
"args": []
}
]
},
// save file
{
"before": ["<leader>", "f", "S"],
"commands": [
{
"command": "workbench.action.files.saveAll"
}
]
},
{
"before": ["<leader>", "f", "t"],
"after": [],
"commands": [
{
"command": "workbench.view.explorer",
"args": []
}
]
},
{
"before": ["<leader>", "f", "y"],
"after": [],
"commands": [
{
"command": "workbench.action.files.copyPathOfActiveFile",
"args": []
}
]
},
{
"before": ["<leader>", "g", "s"],
"after": [],
"commands": [
{
"command": "workbench.view.scm",
"args": []
}
]
},
{
"before": ["<leader>", "j", "="],
"after": [],
"commands": [
{
"command": "editor.action.formatDocument",
"args": []
}
]
},
// beautify files
{
"before": ["<leader>", "="],
"commands": [
{
"command": "editor.action.formatDocument"
}
]
},
{
"before": ["<leader>", "p", "f"],
"after": [],
"commands": [
{
"command": "workbench.action.quickOpen",
"args": []
}
]
},
{
"before": ["<leader>", "p", "l"],
"after": [],
"commands": [
{
"command": "workbench.action.files.openFolder",
"args": []
}
]
},
{
"before": ["<leader>", "p", "p"],
"after": [],
"commands": [
{
"command": "workbench.action.openRecent",
"args": []
}
]
},
{
"before": ["<leader>", "q", "f"],
"after": [],
"commands": [
{
"command": "workbench.action.closeWindow",
"args": []
}
]
},
{
"before": ["<leader>", "q", "r"],
"after": [],
"commands": [
{
"command": "workbench.action.reloadWindow",
"args": []
}
]
},
{
"before": ["<leader>", "q", "q"],
"after": [],
"commands": [
{
"command": "workbench.action.closeWindow",
"args": []
}
]
},
{
"before": ["<leader>", "s", "e"],
"after": [],
"commands": [
{
"command": "editor.action.rename",
"args": []
}
]
},
{
"before": ["<leader>", "s", "j"],
"after": [],
"commands": [
{
"command": "workbench.action.gotoSymbol",
"args": []
}
]
},
{
"before": ["<leader>", "s", "p"],
"after": [],
"commands": [
{
"command": "workbench.action.findInFiles",
"args": []
}
]
},
{
"before": ["<leader>", "s", "P"],
"after": [],
"commands": [
{
"command": "workbench.action.findInFilesWithSelectedText",
"args": []
}
]
},
{
"before": ["<leader>", "T", "F"],
"after": [],
"commands": [
{
"command": "workbench.action.toggleFullScreen",
"args": []
}
]
},
{
"before": ["<leader>", "T", "m"],
"after": [],
"commands": [
{
"command": "workbench.action.toggleMenuBar",
"args": []
}
]
},
{
"before": ["<leader>", "T", "s"],
"after": [],
"commands": [
{
"command": "workbench.action.selectTheme",
"args": []
}
]
},
{
"before": ["<leader>", "T", "t"],
"after": [],
"commands": [
{
"command": "workbench.action.toggleActivityBarVisibility",
"args": []
}
]
},
{
"before": ["<leader>", "v"],
"after": [],
"commands": [
{
"command": "editor.action.smartSelect.grow",
"args": []
}
]
},
{
"before": ["<leader>", "V"],
"after": [],
"commands": [
{
"command": "editor.action.smartSelect.shrink",
"args": []
}
]
},
{
"before": ["<leader>", "w", "w"],
"after": [],
"commands": [
{
"command": "workbench.action.focusNextGroup",
"args": []
}
]
},
// navigation
{
"before": ["leader", "w", "l"],
"commands": [
{
"command": "extension.vim_navigateRight",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "h"],
"commands": [
{
"command": "extension.vim_navigateLeft",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "j"],
"commands": [
{
"command": "extension.vim_navigateDown",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "k"],
"commands": [
{
"command": "extension.vim_navigateUp",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "v"],
"commands": [
{
"command": "workbench.action.splitEditor",
"key": "cmd+\\"
}
]
},
{
"before": ["<leader>", "w", "W"],
"after": [],
"commands": [
{
"command": "workbench.action.focusPreviousGroup",
"args": []
}
]
},
{
"before": ["<leader>", "w", "m"],
"after": [],
"commands": [
{
"command": "workbench.action.maximizeEditor",
"args": []
}
]
}
],
"vim.visualModeKeyBindingsNonRecursive": [
{
"before": ["g", "r"],
"commands": [
{
"command": "editor.action.referenceSearch.trigger",
"when":
"editorHasReferenceProvider && editorTextFocus && !inReferenceSearchEditor && !isInEmbeddedEditor"
}
]
},
{
"before": ["<backspace>"],
"commands": [
{
"command": "deleteLeft",
"when": "editorTextFocus && !editorReadonly"
}
]
},
{
"before": ["<C-a>"],
"commands": [
{
"command": "cursorHome",
"when": "editorTextFocus"
}
]
},
{
"before": ["<C-e>"],
"commands": [
{
"command": "cursorEnd",
"when": "editorTextFocus"
}
]
},
{
"before": ["<C-k>"],
"after": ["D"]
},
{
"before": ["<leader>", "<space>"],
"after": [],
"commands": [
{
"command": "workbench.action.showCommands",
"args": []
}
]
},
{
"before": ["<leader>", "'"],
"after": [],
"commands": [
{
"command": "workbench.action.terminal.toggleTerminal",
"args": []
}
]
},
{
"before": ["<leader>", "1"],
"after": [],
"commands": [
{
"command": "workbench.action.focusFirstEditorGroup",
"args": []
}
]
},
{
"before": ["<leader>", "2"],
"after": [],
"commands": [
{
"command": "workbench.action.focusSecondEditorGroup",
"args": []
}
]
},
{
"before": ["<leader>", "3"],
"after": [],
"commands": [
{
"command": "workbench.action.focusThirdEditorGroup",
"args": []
}
]
},
{
"before": ["<leader>", "b", "b"],
"after": [],
"commands": [
{
"command": "workbench.action.quickOpen",
"args": []
}
]
},
{
"before": ["<CR>"],
"after": [],
"commands": [
{
"command": "workbench.action.quickOpen",
"args": []
}
]
},
{
"before": ["<leader>", "b", "d"],
"after": [],
"commands": [
{
"command": "workbench.action.closeActiveEditor",
"args": []
}
]
},
{
"before": ["<leader>", "b", "n"],
"after": [],
"commands": [
{
"command": "workbench.action.nextEditor",
"args": []
}
]
},
{
"before": ["<leader>", "b", "p"],
"after": [],
"commands": [
{
"command": "workbench.action.previousEditor",
"args": []
}
]
},
{
"before": ["<leader>", "e", "l"],
"after": [],
"commands": [
{
"command": "workbench.actions.view.problems",
"args": []
}
]
},
{
"before": ["<leader>", "f", "e"],
"after": [],
"commands": [
{
"command": "workbench.action.openGlobalSettings",
"args": []
}
]
},
{
"before": ["<leader>", "f", "f"],
"after": [],
"commands": [
{
"command": "workbench.action.files.openFile",
"args": []
}
]
},
{
"before": ["<leader>", "f", "r"],
"after": [],
"commands": [
{
"command": "workbench.action.openRecent",
"args": []
}
]
},
{
"before": ["<leader>", "f", "s"],
"after": [],
"commands": [
{
"command": "workbench.action.files.save",
"args": []
}
]
},
// save file
{
"before": ["<leader>", "f", "S"],
"commands": [
{
"command": "workbench.action.files.saveAll"
}
]
},
{
"before": ["<leader>", "f", "t"],
"after": [],
"commands": [
{
"command": "workbench.view.explorer",
"args": []
}
]
},
{
"before": ["<leader>", "f", "y"],
"after": [],
"commands": [
{
"command": "workbench.action.files.copyPathOfActiveFile",
"args": []
}
]
},
{
"before": ["<leader>", "g", "s"],
"after": [],
"commands": [
{
"command": "workbench.view.scm",
"args": []
}
]
},
{
"before": ["<leader>", "j", "="],
"after": [],
"commands": [
{
"command": "editor.action.formatDocument",
"args": []
}
]
},
// beautify files
{
"before": ["<leader>", "="],
"commands": [
{
"command": "editor.action.formatDocument"
}
]
},
{
"before": ["<leader>", "p", "f"],
"after": [],
"commands": [
{
"command": "workbench.action.quickOpen",
"args": []
}
]
},
{
"before": ["<leader>", "p", "l"],
"after": [],
"commands": [
{
"command": "workbench.action.files.openFolder",
"args": []
}
]
},
{
"before": ["<leader>", "p", "p"],
"after": [],
"commands": [
{
"command": "workbench.action.openRecent",
"args": []
}
]
},
{
"before": ["<leader>", "q", "f"],
"after": [],
"commands": [
{
"command": "workbench.action.closeWindow",
"args": []
}
]
},
{
"before": ["<leader>", "q", "r"],
"after": [],
"commands": [
{
"command": "workbench.action.reloadWindow",
"args": []
}
]
},
{
"before": ["<leader>", "q", "q"],
"after": [],
"commands": [
{
"command": "workbench.action.closeWindow",
"args": []
}
]
},
{
"before": ["<leader>", "s", "e"],
"after": [],
"commands": [
{
"command": "editor.action.rename",
"args": []
}
]
},
{
"before": ["<leader>", "s", "j"],
"after": [],
"commands": [
{
"command": "workbench.action.gotoSymbol",
"args": []
}
]
},
{
"before": ["<leader>", "s", "p"],
"after": [],
"commands": [
{
"command": "workbench.action.findInFiles",
"args": []
}
]
},
{
"before": ["<leader>", "s", "P"],
"after": [],
"commands": [
{
"command": "workbench.action.findInFilesWithSelectedText",
"args": []
}
]
},
{
"before": ["<leader>", "T", "F"],
"after": [],
"commands": [
{
"command": "workbench.action.toggleFullScreen",
"args": []
}
]
},
{
"before": ["<leader>", "T", "m"],
"after": [],
"commands": [
{
"command": "workbench.action.toggleMenuBar",
"args": []
}
]
},
{
"before": ["<leader>", "T", "s"],
"after": [],
"commands": [
{
"command": "workbench.action.selectTheme",
"args": []
}
]
},
{
"before": ["<leader>", "T", "t"],
"after": [],
"commands": [
{
"command": "workbench.action.toggleActivityBarVisibility",
"args": []
}
]
},
{
"before": ["<leader>", "v"],
"after": [],
"commands": [
{
"command": "editor.action.smartSelect.grow",
"args": []
}
]
},
{
"before": ["<leader>", "V"],
"after": [],
"commands": [
{
"command": "editor.action.smartSelect.shrink",
"args": []
}
]
},
{
"before": ["<leader>", "w", "w"],
"after": [],
"commands": [
{
"command": "workbench.action.focusNextGroup",
"args": []
}
]
},
// navigation
{
"before": ["leader", "w", "l"],
"commands": [
{
"command": "extension.vim_navigateRight",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "h"],
"commands": [
{
"command": "extension.vim_navigateLeft",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "j"],
"commands": [
{
"command": "extension.vim_navigateDown",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "k"],
"commands": [
{
"command": "extension.vim_navigateUp",
"when": "vim.active && vim.use<C-w> && !editorTextFocus"
}
]
},
{
"before": ["leader", "w", "v"],
"commands": [
{
"command": "workbench.action.splitEditor",
"key": "cmd+\\"
}
]
},
{
"before": ["<leader>", "w", "W"],
"after": [],
"commands": [
{
"command": "workbench.action.focusPreviousGroup",
"args": []
}
]
},
{
"before": ["<leader>", "w", "m"],
"after": [],
"commands": [
{
"command": "workbench.action.maximizeEditor",
"args": []
}
]
}
]
}
  1. Add the following to your VSCode’s keybindings.json.

Note: You can find your keybindings.json here.
img

[
// unbind "C-k .", needed to bind C-k as kill line
{
"command": "-extension.clipToHtml",
"key": "ctrl+k .",
"when": "editorTextFocus"
},
// (Optional) bind <C-g> as <ESC>
{
"key": "ctrl-g",
"command": "extension.vim_escape",
"when": "editorTextFocus && vim.active && !inDebugRepl"
},
{
"command": "-workbench.action.gotoLine",
"key": "ctrl+g"
},
{
"command": "workbench.action.closeQuickOpen",
"key": "ctrl-g",
"when": "inQuickOpen"
},
{
"command": "workbench.action.exitZenMode",
"key": "ctrl-g ctrl-g",
"when": "inZenMode"
}
]

August 16, 2018 06:04 PM

Spacemacs/Space-Vim Config for Jetbrain IDEs

> Another Spacemacs configuration for Jetbrain IDEs

Recently, I’m working on a React Native project. I have tried using Emacs to do the coding, but I cannot really pick up the whole new stuff without a fancy auto-completion or finding definitions since the syntax of React is so different and special. That’s why I pick up Webstorm as a workaround. And there, I find a way to build my Jetbrain IDEs just like Spacemacs.

Like I said in my previous post, space way is good for Vim users and only Vim can do this because it has other modes other than just insert mode. In this case, key bindings will never be a problem. We are using the sticky key sequences and prefix key for memorization.

Welcome to the heaven!!!

If you’re too lazy to read the whole stuff, grab my .ideavimrc on Github

> The space way

> Leader key

Using space key as the leader is a very popular way of editing, navigation, and commanding. There is never an easy way to get used to new shortcuts, but trust me, you would definitely like it once you use it.

> Sticky key

Think about how you invoke commands in VSCode before. When you want to call the command-palette, you need to put your left hand’s two fingers on Ctrl + Shift key or Command + Shift key and press p. And note that it’s a key chord combination when you actually press these keys.

This looks so stupid when you compare it with just Space Space in Vim’s normal or visual mode. And by saying Space Space, it’s a sticky key binding which means you just type space key twice in sequence. And you can just set your hands as the default typing position shown in this picture.

> Prefix key

Well, now you probably get the point of using space key. But there is more of it.

Since sticky keys are just key sequences, you can cluster a lot of similar commands to a prefix like space f (file related commands). For example, space> f f go to the explorer, space> f s save file and space> f S save all. In this case, you won’t mess up with these keys because they have the same prefix space> f.

> Keybindings

For the normal and visual mode, They are pretty much the same. But they can do much more now in space way.

The space w m and other window pop up combination is just beautiful.

The most used ones are in bold text.

f t is very helpful when you want to navigate to the file you’re currently viewing in the project view.

Note: The leader key is space

KeyDescription
C-iForward
C-oGo back
g dGo to declaration
g hGo to Documentation
g rFind Usages
g sGo to Symbol
leader ’Active terminal window
leader Rreload ~/.ideavimrc
leader a aSelect All
leader a lPrompt action list
leader b b (<CR>)Recent files (You can still use command+e or ctrl+e)
leader b iActive structure tool window
leader b uReopen Closed Tab
leader c cGo to Class
leader d DDebug Class
leader d dDebug
leader e eshow error description
leader f TSelect current file in project view
leader f bShow Bookmarks
leader f dSmart search launcher (You have to install Dash or Zeal first)
leader f fSearch Everywhere
leader f ssave all files (I still use command+s or ctrl+s)
leader f tActive file tree window
leader i mImplement Methods
leader g S/Active version control window
leader g sVsc quick list pop up
leader j iFire structure pop up (similar to structure tool)
leader j jAce Action
leader j lAce Line Action
leader m =beautify file
leader r RRun Class
leader r pReplace in project
leader r rRun
leader s sStop
leader s pSearch in project
leader spaceGo to Action
leader t bToggle Bookmark
leader t tToggle Line Breakpoint
leader w [lhjk]navigate window
leader w cclose window
leader w mhide all windows except the editor tabs (You can invoke again to revert)
leader w ssplit window horizontally
leader w vsplit window vertically
leader w zToggle Zen mode
z Ccollapse all region
z Oexpand all region
z ccollapse region
z oexpand region

> Install

  1. Install ideaVim and create a .ideavimrc file in home directory, just like ~/.ideavimrc.

In case you want to sync your settings across multiple machines, you should checkout the Setting Repository here.

  1. If you want to use the Emacs key in Vim’s insert mode, which is the hybrid mode in Spacemacs, copy the following script to ~/.ideavimrc.
" ============================================================================
" emacs keymaping for cursor movement{{{
" You have to unbind C-g before it works
" ============================================================================
nmap <c-g> <Esc>
vmap <c-g> <Esc>
imap <c-g> <Esc>a
nmap <c-a> ^
nmap <c-e> $
vmap <c-a> ^
vmap <c-e> $
imap <c-e> <Esc>A
imap <c-a> <Esc>I
imap <c-d> <del>
inoremap <c-p> <up>
inoremap <c-n> <down>
" command line
cnoremap <C-a> <Home>
cnoremap <C-e> <End>
"}}}

Note: You have to disable the C-a, C-e in Jetbrain IDE to have the visual mode working correctly.

You can click the from here to find the action by key.

  1. To bind the actions under space, put the following script in the ~/.ideavimrc.

The ugly <Backspace><Backspace><Backspace><Backspace><Backspace> is because when we enter the command mode from visual mode, we have :'<,'>. The extra chars need to be deleted before we invoke the actions.

let mapleader = " "

" ============================================================================
" key bindings for quickly moving between windows
" h left, l right, k up, j down
" ============================================================================
nmap <leader>wh <c-w>h
nmap <leader>wl <c-w>l
nmap <leader>wk <c-w>k
nmap <leader>wj <c-w>j
nmap <leader>wv <c-w>v
nmap <leader>ws <c-w>s
nmap <leader>wc <c-w>c
nmap <leader>wm :action HideAllWindows<CR>
nmap <leader>wz :action ToggleDistractionFreeMode<CR>

vmap <leader>wh <c-w>h
vmap <leader>wl <c-w>l
vmap <leader>wk <c-w>k
vmap <leader>wj <c-w>j
vmap <leader>wv <c-w>v
vmap <leader>ws <c-w>s
vmap <leader>wc <c-w>c
vmap <leader>wm :<Backspace><Backspace><Backspace><Backspace><Backspace>action HideAllWindows<CR>
vmap <leader>wz :<Backspace><Backspace><Backspace><Backspace><Backspace>action ToggleDistractionFreeMode<CR>

" ============================================================================
" expand and collapse
" ============================================================================
nmap zO :action ExpandAllRegions<CR>
nmap zo :action ExpandRegion<CR>
nmap zc :action CollapseRegion<CR>
nmap zC :action CollapseAllRegions<CR>

" ============================================================================
" IDE actions
" ============================================================================

nmap <CR> :action RecentFiles<CR>
nmap <c-i> :action Forward<CR>
nmap <c-o> :action Back<CR>
nmap <leader>' :action ActivateTerminalToolWindow<CR>
nmap <leader><Space> :action GotoAction<CR>
nmap <leader><tab> :action RecentFiles<CR>
nmap <leader>aa :action $SelectAll<CR>
nmap <leader>al :actionlist<CR>
nmap <leader>bb :action RecentFiles<CR>
nmap <leader>bi :action ActivateStructureToolWindow<CR>
nmap <leader>bu :action ReopenClosedTab<CR>
nmap <leader>cc :action GotoClass<CR>
nmap <leader>dD :action DebugClass<CR>
nmap <leader>dd :action Debug<CR>
nmap <leader>ee :action ShowErrorDescription<CR>
nmap <leader>fT :action SelectInProjectView<CR>
nmap <leader>fb :action ShowBookmarks<CR>
nmap <leader>fd :action SmartSearchAction<CR>
nmap <leader>ff :action SearchEverywhere<CR>
nmap <leader>fs :action SaveAll<CR>
nmap <leader>ft :action ActivateProjectToolWindow<CR>
nmap <leader>im :action ImplementMethods<CR>
nmap <leader>ji :action FileStructurePopup<CR>
nmap <leader>jj :action AceAction<CR>
nmap <leader>jl :action AceLineAction<CR>
nmap <leader>m= :action ReformatCode<CR>
nmap <leader>rR :action RunClass<CR>
nmap <leader>rr :action Run<CR>
nmap <leader>ss :action Stop<CR>
nmap <leader>tb :action ToggleBookmark<CR>
nmap <leader>tt :action ToggleLineBreakpoint<CR>
nmap gd :action GotoDeclaration<CR>
nmap gh :action QuickJavaDoc<CR>
nmap gr :action FindUsages<CR>
nmap gs :action GotoSymbol<CR>

vmap <CR> :<Backspace><Backspace><Backspace><Backspace><Backspace>action RecentFiles<CR>
vmap <c-i> :<Backspace><Backspace><Backspace><Backspace><Backspace>action Forward<CR>
vmap <c-o> :<Backspace><Backspace><Backspace><Backspace><Backspace>action Back<CR>
vmap <leader>' :<Backspace><Backspace><Backspace><Backspace><Backspace>action ActivateTerminalToolWindow<CR>
vmap <leader><Space> :<Backspace><Backspace><Backspace><Backspace><Backspace>action GotoAction<CR>
vmap <leader><tab> :<Backspace><Backspace><Backspace><Backspace><Backspace>action RecentFiles<CR>
vmap <leader>aa :<Backspace><Backspace><Backspace><Backspace><Backspace>action $SelectAll<CR>
vmap <leader>al :<Backspace><Backspace><Backspace><Backspace><Backspace>actionlist<CR>
vmap <leader>bb :<Backspace><Backspace><Backspace><Backspace><Backspace>action RecentFiles<CR>
vmap <leader>bi :<Backspace><Backspace><Backspace><Backspace><Backspace>action ActivateStructureToolWindow<CR>
vmap <leader>bu :<Backspace><Backspace><Backspace><Backspace><Backspace>action ReopenClosedTab<CR>
vmap <leader>cc :<Backspace><Backspace><Backspace><Backspace><Backspace>action GotoClass<CR>
vmap <leader>dD :<Backspace><Backspace><Backspace><Backspace><Backspace>action DebugClass<CR>
vmap <leader>dd :<Backspace><Backspace><Backspace><Backspace><Backspace>action Debug<CR>
vmap <leader>ee :<Backspace><Backspace><Backspace><Backspace><Backspace>action ShowErrorDescription<CR>
vmap <leader>fT :<Backspace><Backspace><Backspace><Backspace><Backspace>action SelectInProjectView<CR>
vmap <leader>fb :<Backspace><Backspace><Backspace><Backspace><Backspace>action ShowBookmarks<CR>
vmap <leader>fd :<Backspace><Backspace><Backspace><Backspace><Backspace>action SmartSearchAction<CR>
vmap <leader>ff :<Backspace><Backspace><Backspace><Backspace><Backspace>action SearchEverywhere<CR>
vmap <leader>fs :<Backspace><Backspace><Backspace><Backspace><Backspace>action SaveAll<CR>
vmap <leader>ft :<Backspace><Backspace><Backspace><Backspace><Backspace>:action ActivateProjectToolWindow<CR>
vmap <leader>im :<Backspace><Backspace><Backspace><Backspace><Backspace>action ImplementMethods<CR>
vmap <leader>ji :<Backspace><Backspace><Backspace><Backspace><Backspace>action FileStructurePopup<CR>
vmap <leader>m= :<Backspace><Backspace><Backspace><Backspace><Backspace>action ReformatCode<CR>
vmap <leader>rR :<Backspace><Backspace><Backspace><Backspace><Backspace>action RunClass<CR>
vmap <leader>rr :<Backspace><Backspace><Backspace><Backspace><Backspace>action Run<CR>
vmap <leader>ss :<Backspace><Backspace><Backspace><Backspace><Backspace>action Stop<CR>
vmap <leader>tb :<Backspace><Backspace><Backspace><Backspace><Backspace>action ToggleBookmark<CR>
vmap <leader>tt :<Backspace><Backspace><Backspace><Backspace><Backspace>action ToggleLineBreakpoint<CR>
vmap gd :<Backspace><Backspace><Backspace><Backspace><Backspace>action GotoDeclaration<CR>
vmap gr :<Backspace><Backspace><Backspace><Backspace><Backspace>action FindUsages<CR>

" tab is used in karabiner as <C-i>, <C-d> as delete
nmap <tab> :action Forward<CR>
nmap <delete> <C-d>
vmap <tab> :<Backspace><Backspace><Backspace><Backspace><Backspace>action Forward<CR>
vmap <delete> <C-d>

" Reload .ideavimrc
nmap <leader>R :source ~/.ideavimrc<CR>
vmap <leader>R :<Backspace><Backspace><Backspace><Backspace><Backspace>source ~/.ideavimrc<CR>

" check the action list
nmap <leader>al :actionlist<CR>
vmap <leader>al :a<Backspace><Backspace><Backspace><Backspace><Backspace>ctionlist<CR>

" git
nmap <leader>gs :action Vcs.QuickListPopupAction<CR>
vmap <leader>gs :<Backspace><Backspace><Backspace><Backspace><Backspace>action Vcs.QuickListPopupAction<CR>
nmap <leader>gS :action ActivateVersionControlToolWindow<CR>
vmap <leader>gS :<Backspace><Backspace><Backspace><Backspace><Backspace>action ActivateVersionControlToolWindow<CR>

" search in project
nmap <leader>sp :action FindInPath<CR>
vmap <leader>sp :<Backspace><Backspace><Backspace><Backspace><Backspace>action FindInPath<CR>

" replace in project
nmap <leader>rp :action ReplaceInPath<CR>
vmap <leader>rp :<Backspace><Backspace><Backspace><Backspace><Backspace>action FindInPath<CR>
  1. The multi-cursor action does not work correctly as well as the extend region and shrink region. They mess up some visual selection in Vim and the original selection. That’s the reason. But so far I cannot do anything. So I just put the script here in case they work later on.
" select occurrence, they do not work when editing
nmap mn :action SelectNextOccurrence<CR>
nmap mp :action UnselectPreviousOccurrence<CR>
nmap ma :action SelectAllOccurrences<CR>
vmap mn :<Backspace><Backspace><Backspace><Backspace><Backspace>action SelectNextOccurrence<CR>
vmap mp :<Backspace><Backspace><Backspace><Backspace><Backspace>action UnselectPreviousOccurrence<CR>
vmap ma :<Backspace><Backspace><Backspace><Backspace><Backspace>action SelectAllOccurrences<CR>
  1. There are other options you might want to add.
set gdefault
set smartcase


" use system clipboard
set clipboard=unnamedplus,unnamed

set surround

" Allow backspace and cursor keys to cross line boundaries
set whichwrap+=<,>,h,l

" black hole register
vmap <backspace> "_d
vmap <del> "_d

August 16, 2018 06:04 PM

Swift Basics

> Constants and Variables

If a stored value in your code is not going to change, always declare it as a constant with the let keyword. Use variables only for storing values that need to be able to change.

let maximumNumberOfLoginAttempts = 10
var currentLoginAttempt = 0

> Type Annotations

It is rare that you need to write type annotations in practice. If you provide an initial value for a constant or variable at the point that it is defined, Swift can almost always infer the type to be used for that constant or variable, as described in Type Safety and Type Inference.

var welcomeMessage: String
welcomeMessage = "Hello"

In the welcomeMessage example above, no initial value is provided, and so the type of the welcomeMessage variable is specified with a type annotation rather than being inferred from an initial value.

> Naming Constants and Variables

Constant and variable names can contain almost any character, including Unicode characters:

let π = 3.14159
let 你好 = "你好世界"
let 🐶🐮 = "dogcow"

> Printing

Swift uses string interpolation to include the name of a constant or variable as a placeholder in a longer string, and to prompt Swift to replace it with the current value of that constant or variable. Wrap the name in parentheses and escape it with a backslash before the opening parenthesis:

print("The current value of friendlyWelcome is \(friendlyWelcome)")”

> UInt

Swift also provides an unsigned integer type, UInt, which has the same size as the current platform’s native word size:

  • On a 32-bit platform, UInt is the same size as UInt32.
  • On a 64-bit platform, UInt is the same size as UInt64.

> Floating-Point Numbers

Floating-point types can represent a much wider range of values than integer types, and can store numbers that are much larger or smaller than can be stored in an Int. Swift provides two signed floating-point number types:

  • Double represents a 64-bit floating-point number.
  • Float represents a 32-bit floating-point number.

Double has a precision of at least 15 decimal digits, whereas the precision of Float can be as little as 6 decimal digits.

> Type Safety and Type Inference

Because of type inference, Swift requires far fewer type declarations than languages such as C or Objective-C. Constants and variables are still explicitly typed, but much of the work of specifying their type is done for you.

Type inference is particularly useful when you declare a constant or variable with an initial value. This is often done by assigning a literal value (or literal) to the constant or variable at the point that you declare it.

> Numeric Literals

Integer literals can be written as:

  • A decimal number, with no prefix
  • A binary number, with a 0b prefix
  • An octal number, with a 0o prefix
  • A hexadecimal number, with a 0x prefix

All of these integer literals have a decimal value of 17:

let decimalInteger = 17
let binaryInteger = 0b10001 // 17 in binary notation
let octalInteger = 0o21 // 17 in octal notation
let hexadecimalInteger = 0x11 // 17 in hexadecimal notation”

Floating-point literals can be decimal (with no prefix), or hexadecimal (with a 0x prefix). They must always have a number (or hexadecimal number) on both sides of the decimal point. Decimal floats can also have an optional exponent, indicated by an uppercase or lowercase e; hexadecimal floats must have an exponent, indicated by an uppercase or lowercase p.

For decimal numbers with an exponent of exp, the base number is multiplied by 10exp:

1.25e2 means 1.25 x 102, or 125.0. 1.25e-2 means 1.25 x 10-2, or 0.0125. For hexadecimal numbers with an exponent of exp, the base number is multiplied by 2exp:

0xFp2 means 15 x 22, or 60.0. 0xFp-2 means 15 x 2-2, or 3.75. All of these floating-point literals have a decimal value of 12.1875:

let decimalDouble = 12.1875
let exponentDouble = 1.21875e1
let hexadecimalDouble = 0xC.3p0

Numeric literals can contain extra formatting to make them easier to read. Both integers and floats can be padded with extra zeros and can contain underscores to help with readability. Neither type of formatting affects the underlying value of the literal:

let paddedDouble = 000123.456
let oneMillion = 1_000_000
let justOverOneMillion = 1_000_000.000_000_1

> Type Aliases

Type aliases define an alternative name for an existing type. You define type aliases with the typealias keyword.

Type aliases are useful when you want to refer to an existing type by a name that is contextually more appropriate, such as when working with data of a specific size from an external source:

typealias AudioSample = UInt16

> Tuples

Tuples group multiple values into a single compound value. The values within a tuple can be of any type and do not have to be of the same type as each other.

In this example, (404, “Not Found”) is a tuple that describes an HTTP status code. An HTTP status code is a special value returned by a web server whenever you request a web page. A status code of 404 Not Found is returned if you request a webpage that doesn’t exist.

let http404Error = (404, "Not Found")
// http404Error is of type (Int, String), and equals (404, "Not Found")

If you only need some of the tuple’s values, ignore parts of the tuple with an underscore (_) when you decompose the tuple:

let (justTheStatusCode, _) = http404Error
print("The status code is \(justTheStatusCode)")
// Prints "The status code is 404"

Alternatively, access the individual element values in a tuple using index numbers starting at zero:

print("The status code is \(http404Error.0)")
// Prints "The status code is 404"
print("The status message is \(http404Error.1)")
// Prints "The status message is Not Found"

You can name the individual elements in a tuple when the tuple is defined:

let http200Status = (statusCode: 200, description: "OK")

If you name the elements in a tuple, you can use the element names to access the values of those elements:

print("The status code is \(http200Status.statusCode)")
// Prints "The status code is 200"
print("The status message is \(http200Status.description)")
// Prints "The status message is OK

Note: Tuples are useful for temporary groups of related values. They are not suited to the creation of complex data structures. If your data structure is likely to persist beyond a temporary scope, model it as a class or structure, rather than as a tuple. For more information, see Classes and Structures.

> Optionals

You use optionals in situations where a value may be absent. An optional represents two possibilities: Either there is a value, and you can unwrap the optional to access that value, or there isn’t a value at all.

The example below uses the initializer to try to convert a String into an Int:

let possibleNumber = "123"
let convertedNumber = Int(possibleNumber)
// convertedNumber is inferred to be of type "Int?", or "optional Int"

Because the initializer might fail, it returns an optional Int, rather than an Int. An optional Int is written as Int?, not Int. The question mark indicates that the value it contains is optional, meaning that it might contain some Int value, or it might contain no value at all. (It can’t contain anything else, such as a Bool value or a String value. It’s either an Int, or it’s nothing at all.)

> If Statements and Forced Unwrapping

Once you’re sure that the optional does contain a value, you can access its underlying value by adding an exclamation mark (!) to the end of the optional’s name. The exclamation mark effectively says, “I know that this optional definitely has a value; please use it.” This is known as forced unwrapping of the optional’s value:

if convertedNumber != nil {
print("convertedNumber has an integer value of \(convertedNumber!).")
}
// Prints "convertedNumber has an integer value of 123."

NOTE: Trying to use ! to access a nonexistent optional value triggers a runtime error. Always make sure that an optional contains a non-nil value before using ! to force-unwrap its value.

> Optional Binding

You use optional binding to find out whether an optional contains a value, and if so, to make that value available as a temporary constant or variable. Optional binding can be used with if and while statements to check for a value inside an optional, and to extract that value into a constant or variable, as part of a single action.

Write an optional binding for an if statement as follows:

 if let constantName = someOptional {
statements
}

> implicitly unwrapped optional

let possibleString: String? = "An optional string."
let forcedString: String = possibleString! // requires an exclamation mark

let assumedString: String! = "An implicitly unwrapped optional string."
let implicitString: String = assumedString // no need for an exclamation mark

You can think of an implicitly unwrapped optional as giving permission for the optional to be unwrapped automatically whenever it is used. Rather than placing an exclamation mark after the optional’s name each time you use it, you place an exclamation mark after the optional’s type when you declare it.

NOTE: If an implicitly unwrapped optional is nil and you try to access its wrapped value, you’ll trigger a runtime error. The result is exactly the same as if you place an exclamation mark after a normal optional that does not contain a value.

August 16, 2018 06:04 PM

Org to Wordpress with org2blog

> Publish with Org2Blog and Solution to non-ascii when posting to Wordpress

> Install packages

Install org2blog. I put the package in my own emacs configuration folder. Path to org2blog: ~/.spacemacs.d/layers/org2blog/.

org2blog depends on

  1. xml-rpc available at Launchpad Launchpad
  2. metaweblog.el available here

To better manage the packages, I just put the two packages above right under the same path to my org2blog.

> Configuring Emacs

Put following code in your emacs configuration file, e.g. ~/.emacs.d/init.el. Of course, change to your private infomation, including my-blog, url, username. You need to put /xmlrpc.php after your url. That’s for XML-RPC server of your homepage. It only accepts POST request.

;; Load your own org2blog path by using load-path.
(setq load-path (cons "~/.spacemacs.d/layers/org2blog/" load-path))
(require 'org2blog-autoloads)
(require 'auth-source) ;; or nothing if already in the load-path
(setq org2blog/wp-blog-alist
'(("my-blog"
:url "https://ztlevi.wordpress.com/xmlrpc.php"
:username "ztlevi")))
(let (credentials)
;; only required if your auth file is not already in the list of auth-sources
(add-to-list 'auth-sources "~/.netrc")
(setq credentials (auth-source-user-and-password "wp-ztlevi"))
(setq org2blog/wp-blog-alist
`(("my-blog"
:url "https://ztlevi.wordpress.com/xmlrpc.php"
:username ,(car credentials)
:password ,(cadr credentials)))))

Your ~/.netrc file looks like this. Change the username and yourpassword to your real ones.

machine wp-ztlevi login username password your_password

wp-ztlevi is the authid to find your private information from the ~/.netrc file.

> Useage

  1. M-x org2blog/wp-new-entry : Create a new templete file.
  2. M-x org2blog/wp-login : Login to your wordpress blog.
  3. M-x org2blog/wp-post-buffer : Used to post your org file as draft.
  4. M-x org2blog/wp-post-buffer-and-publish : Publish your org file right away.

> Solution to non-ascii on Wordpress

Since Wordpress does not support non-ascii when you post. We need to clear out the non-ascii characters before we post. Otherwise it will failed with a structure problem like this.

imgSo annoying when I first met this problem. I really had no ideas about this.

/Users/ztlevi/Dropbox/Beautify/OldWallPaper/001.jpg

<param>
<value>
<boolean>0</boolean>
</value>
</param>

And Here is the Solution. Found in a Japanese blog :). http://blog.somof.net/?p=1310

测试是否能上传到blog :)

I put some Chinese right here. Well, if you see the line above, that means it succeeds.

Add the following codes to your emacs configuration and you are good to go.

(advice-add 'url-http-create-request :override
'url-http-create-request-debug)
(defun url-http-create-request-debug (&optional ref-url)
"Create an HTTP request for <code>url-http-target-url', referred to by REF-URL."
(let* ((extra-headers)
(request nil)
(no-cache (cdr-safe (assoc "Pragma" url-http-extra-headers)))
(using-proxy url-http-proxy)
(proxy-auth (if (or (cdr-safe (assoc "Proxy-Authorization"
url-http-extra-headers))
(not using-proxy))
nil
(let ((url-basic-auth-storage
'url-http-proxy-basic-auth-storage))
(url-get-authentication url-http-proxy nil 'any nil))))
(real-fname (url-filename url-http-target-url))
(host (url-http--encode-string (url-host url-http-target-url)))
(auth (if (cdr-safe (assoc "Authorization" url-http-extra-headers))
nil
(url-get-authentication (or
(and (boundp 'proxy-info)
proxy-info)
url-http-target-url) nil 'any nil))))
(if (equal "" real-fname)
(setq real-fname "/"))
(setq no-cache (and no-cache (string-match "no-cache" no-cache)))
(if auth
(setq auth (concat "Authorization: " auth "\r\n")))
(if proxy-auth
(setq proxy-auth (concat "Proxy-Authorization: " proxy-auth "\r\n")))

;; Protection against stupid values in the referrer
(if (and ref-url (stringp ref-url) (or (string= ref-url "file:nil")
(string= ref-url "")))
(setq ref-url nil))

;; We do not want to expose the referrer if the user is paranoid.
(if (or (memq url-privacy-level '(low high paranoid))
(and (listp url-privacy-level)
(memq 'lastloc url-privacy-level)))
(setq ref-url nil))

;; url-http-extra-headers contains an assoc-list of
;; header/value pairs that we need to put into the request.
(setq extra-headers (mapconcat
(lambda (x)
(concat (car x) ": " (cdr x)))
url-http-extra-headers "\r\n"))
(if (not (equal extra-headers ""))
(setq extra-headers (concat extra-headers "\r\n")))

;; This was done with a call to </code>format'. Concatenating parts has
;; the advantage of keeping the parts of each header together and
;; allows us to elide null lines directly, at the cost of making
;; the layout less clear.
(setq request
(concat
;; The request
(or url-http-method "GET") " "
(url-http--encode-string
(if using-proxy (url-recreate-url url-http-target-url) real-fname))
" HTTP/" url-http-version "\r\n"
;; Version of MIME we speak
"MIME-Version: 1.0\r\n"
;; (maybe) Try to keep the connection open
"Connection: " (if (or using-proxy
(not url-http-attempt-keepalives))
"close" "keep-alive") "\r\n"
;; HTTP extensions we support
(if url-extensions-header
(format
"Extension: %s\r\n" url-extensions-header))
;; Who we want to talk to
(if (/= (url-port url-http-target-url)
(url-scheme-get-property
(url-type url-http-target-url) 'default-port))
(format
"Host: %s:%d\r\n" host (url-port url-http-target-url))
(format "Host: %s\r\n" host))
;; Who its from
(if url-personal-mail-address
(concat
"From: " url-personal-mail-address "\r\n"))
;; Encodings we understand
(if (or url-mime-encoding-string
;; MS-Windows loads zlib dynamically, so recheck
;; in case they made it available since
;; initialization in url-vars.el.
(and (eq 'system-type 'windows-nt)
(fboundp 'zlib-available-p)
(zlib-available-p)
(setq url-mime-encoding-string "gzip")))
(concat
"Accept-encoding: " url-mime-encoding-string "\r\n"))
(if url-mime-charset-string
(concat
"Accept-charset: "
(url-http--encode-string url-mime-charset-string)
"\r\n"))
;; Languages we understand
(if url-mime-language-string
(concat
"Accept-language: " url-mime-language-string "\r\n"))
;; Types we understand
"Accept: " (or url-mime-accept-string "*/*") "\r\n"
;; User agent
(url-http-user-agent-string)
;; Proxy Authorization
proxy-auth
;; Authorization
auth
;; Cookies
(when (url-use-cookies url-http-target-url)
(url-http--encode-string
(url-cookie-generate-header-lines
host real-fname
(equal "https" (url-type url-http-target-url)))))
;; If-modified-since
(if (and (not no-cache)
(member url-http-method '("GET" nil)))
(let ((tm (url-is-cached url-http-target-url)))
(if tm
(concat "If-modified-since: "
(url-get-normalized-date tm) "\r\n"))))
;; Whence we came
(if ref-url (concat
"Referer: " ref-url "\r\n"))
extra-headers
;; Length of data
(if url-http-data
(concat
"Content-length: " (number-to-string
(length url-http-data))
"\r\n"))
;; End request
"\r\n"
;; Any data
url-http-data))
;; Bug#23750
;;(unless (= (string-bytes request)
;; (length request))
;; (message " text byte %d vs %d length" (string-bytes request) (length request)))
;;(message "===============================")
;;(error "Multibyte text in HTTP request: %s" request))
(url-http-debug "Request is: \n%s" request)
request))

BTW, you can add the function occur-non-ascii to your emacs configuration. It will pop lines with non-ascii characters in a buffer. Press e to edit.

;; occur non ascii, used to check non-ascii in Wordpress
(defun occur-non-ascii ()
"Find any non-ascii characters in the current buffer."
(interactive)
(push (if (region-active-p)
(buffer-substring-no-properties
(region-beginning)
(region-end))
(let ((sym (thing-at-point 'symbol)))
(when (stringp sym)
(regexp-quote sym))))
regexp-history)
(deactivate-mark)
(occur "[^[:ascii:]]"))

If the highlight for the matches does not look so clear. Put the following line in your emacs custom setting for faces. Change the background and foreground color to whatever you want.

(custom-set-faces
'(match ((t (:background "DeepSkyBlue1" :foreground "gray90" :weight bold))))
)

August 16, 2018 06:04 PM

Quick solution for lagging in Chrome with Nvidia Hackintosh

> Introduction

For those of you love simplicity and complexity that Chrome provides, and also running a Hackintosh with Nvidia drivers, you might notice it’s super lagging when browsing or even just open your Chrome.

Note: The version I’m running: Chrome 64.0.3282.140, MacOs 10.13.3

I’m not if it’s Nvidia’s fault or Apple’s, but it seems like they have a terrible partnership. So, unless you try to buy a AMD GPU, I suppose you would like to disable you hardware acceleration in Google Chrome. I feel like my Chrome has revived after all the suffer.

> Steps:

To disable hardware acceleration in Google Chrome, follow the steps below:

  • Open Google Chrome.
  • Click Customize and Control Google Chrome > Settings.
  • Click on Show advanced settings and scroll to the System section.
  • Uncheck Use hardware acceleration when available and restart Google Chrome.

August 16, 2018 06:04 PM

Java: you do not know I

Some basic knowledge of Java in the book[1]. Well, I pick the title “you don’t know”. Precisely, it’s something I don’t know while you may already knew years ago. But it just sounds so stupid to named after “Java: I don’t know”…

Your interviewer may be equally—or more—impressed if you can derive the answer than if you automatically knew it.

> Overriding

public double computeArea(Circle c) {...}
public double computeArea(Square s) {...}

Overriding, however, occurs when a method shares the same name and function signature as another method in its super class.

> Collection Framework

Java’s collection framework is incredibly useful.

  • ArrayList: An ArrayList is dynamically resizing array, which grows as you insert elements.
  • Vector: A vector is very similar to ArrayList, while Vector is synchronized. This means if one thread is working on Vector, no other thread can get a hold of it. Unlike ArrayList, only one thread can perform an operation on vector at a time.
  • LinkedList: LinkedList is, of course, Java’s built-in ListkedList class. Though it rarely comes up in an interview, it’s useful to study because it demonstrates some of the syntax for an iterator.
  • HashMap: The HashMap collection is widely used, both in interviews and in the real world. Also Set collections like HashSet are required to learn.

> Private Constructor

Q: In terms of inheritance, what is the effect of keeping a constructor private?

This has direct implications for inheritance, since a subclass class calls its parent’s constructor. Who, other than A, can access A’s private methods and constructor? A’s inner classes can. This means, the class A can be inherited, but only by its own or its parent’s inner classes.

> Return from Finally

Q: In Java, does the finally block get executed if we insert a return statement inside the try block o a try-catch-finally?

Yes, it will get executed. The finally block always executes when the try block exits. This ensures that the finally block is executed even if an unexpected exception occurs. But finally is useful for more than just exception handling — it allows the programmer to avoid having cleanup code accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally block is always a good practice, even when no exceptions are anticipated.

Note: If the JVM exits while the try or catch code is being executed, then the finally block may not execute. Likewise, if the thread executing the try or catch code is interrupted or killed, the finally block may not execute even though the application as a whole continues.

> What’s the difference between final, finally, and finalize?

Despite their similar sounding names, final, finally and finalize have very different purposes.
To speak in very general terms:

  1. The final is used to control whether a variable, method, or class is “changeable”.

The final statement has a different meaning depending on context.

  • When applied to a variable(primitive): The value of the variable cannot change.
  • When applied to a variable(reference): The reference variable cannot point to any other object on the heap.
  • When applied to a method: The method cannot be overridden.
  • When applied to a class: The class cannot. be subclassed
  1. The finally keyword is used in a try/catch block to ensure that a segment of code is always executed.

There is an optional finally block after the try block or after the catch block. The finally block is often used to write the clean-up code. It will be executed after the try and catch blocks, but before control transfers back to its origin.

  1. The finalize() method is called by the garbage collector once it determines that no more references exist.

The automatic garbage collector calls the finalized() method just before actually destroying the object. A class can therefore override the finalized() method from the Object class in order to define custom behavior during garbage collection.

protected void finalize() throws Throwable {
/* Close open files, release resources, etc */
}

> Generics vs Templates

Q: Explain the difference between templates in C++ dand generics in Java.

Many programmers consider templates and generics to be essentially equivalent because both allow you to do something like List. But, how each language does this, and why, varies significantly.

The implementation of Java generics is rooted in an idea of “type erasure”. This technique eliminates the parameterized types then source code is translated to the Java Virtual Machine(JVM) byte code.

For example, suppose you have the Java code below:

Vector<String> vector = new Vector<String>();
vector.add(new String("hello"));
String str = vector.get(0)

During the compilation, this code is re-written into:

Vector vector = new Vector();
vector.add(new String("hello"));
String str = (String) vector.get(0);

The use of Java generics didn’t really change much about our capabilities; it just made things a bit prettier. For this reason, Java generics are sometimes called “syntactic sugar”.

This is quite different from C++. In C++, templates are essentially a glorified macro set, with the compiler creating a new copy of the template code for each type.

In Java, static variables are shared across instances of Class, regardless of the different type parameters.

There are other differences between Java generics and C++ templates.

  • C++ templates can use primitive types, like int, Java cannot and must instead use Integer.
  • In Java, you can restrict the template’s type parameters to be of a certain type. For instance, you might use generics to implement a CardDeck and specify that the type parameter must extend from CardGame.
  • In C++, the type parameter can be instantiated, whereas Java does not support this.
  • In Java, the type parameter cannot be used for static methods and variables, since these would be shared between classes. In C++, these classes are different, so the type parameter can be used for static methods and variables.
  • In Java, all instances of the same class, regardless of their type parameters, are the same type. The type parameters are erased at runtime. In C++, instances with different type parameters are different types.

  1. Cracking the Coding Interview, 6th Edition.

August 16, 2018 06:04 PM

Hexo embeded with tags (Youtube, Twitter, Instagram)

> Embed web pages in your post

Recently, I found Hugo, which is another static site generator, comes with some useful shortcodes that allows you embed html figure, instagram, speakerdeck, youtube, twitter and so on in your post. That’s a great feature for some social guys.

And of course, we can do this in hexo with some plugins.

Thanks god. I don’t even play Instagram, twitter. And my youtube channel is just full with school stuff. What a boring man am I.😂😂😂 So I just put other people’s nice one here as examples.

> Youtube

For youtube or other video resources, you can embed videos with hexo-tag-video. Thanks geekplux for this interesting plugin.

Very easy to install. Here is an example.

  • embed code for youtube
{% video <iframe width="560" height="315" src="https://www.youtube.com/embed/k5X2Hb3tc2s" frameborder="0" allow="autoplay; encrypted-media" allowfullscreen></iframe> %}

> Instagram & Twitter

For Instagram, hexo-tag-instagram is built by tea3. He built hexo-tag-twitter as well. Great job done, tea3!

  • embed code for instgram
{% instagram instgram-url %}

  • embed code for twitter
{% twitter tweet-url %}

August 16, 2018 06:04 PM

Git Commands

Table of Contents

> Git Commands

> Create a new repository on the command line

  1. Creating repository

git commandsDescription
git initInitialize a git project
git add . or * means all new files
git rm —cached -Remove all files from cache
git commitCommit your changes to repository
git commit -aCombined the add and commit step
git statusCheck what the file changed
git diff readme.mdSee the changes of readme.md
git diff v2.5 HEADCompare the current HEAD to v2.5

The commit you are currently on is known as the HEAD commit.

  1. Version rollback

git commandsDescription
git logShow the logs(SHA)
git log --pretty=onelineShow the logs concisely
git reflogGet the version number(first 7 characters of the SHA)
git reset --hard HEAD^Go back to the last version, --hard is used to reset the index and working directory
git reset --hard HEAD@{n}Go back to the nth versions before
git reset --hard version_numberReset to the specific version
  1. Undo changes and delete files

git commandsDescription
git checkout HEAD Undo the file changes and recover the file to the HEAD
img3.1 Delete commits------------------
git commandsDescription
Git glogSee commit ids
Git rebase -i commit_idEdit the commits from HEAD to commit_id (delete line to remove commits)
Git push -f origin branchForce push to origin branch
  1. Remote repository

> Step 1: Create SSH Key

ssh-keygen -t rsa -C “your email” —> generate puclic/private rsa key pair

> Step 2: Open github -> settings -> SSH and New GPG keys -> New SSH keys

Fill anything in the title and copy the id_rsa.pub to the key text box. Then click Add Key.

> a. Add remote repository

git commandsDescription
git remote add origin https://github.com/ztlevi/MRS.gitAdd remote repository
git remote add origin git@github.com:ztlevi/MRS.gitThe same.
git push -u origin/dev dev
= git push -u origin dev
= git push origin dev
Set upstream for git pull/status. dev branch will be created if not existed.
git checkout origin/dev –b devCheckout to dev branch and set upstream to origin/dev. Contain the next command
git branch -u origin/dev dev
= git branch -u origin dev
dev set up to track remote branch dev from origin.

After that, use git push/git push origin master

> b. Clone the remote repository

git clone remote_location //clone_directory

Remote location can be local or online location, such as http/ssh. If there is no clone_directory, then the default directory is the root directory.

  1. Create and merge branch

git commandsDescription
git checkout -b Create and switch to the branch created. This command equals
the following two commonds git branch dev and git checkout dev
git branch (-v)List all the branches
git branch Create branch
git checkout Switch branch and will automaticlly merge
git branch -d Delete branch
git push origin -d DeleteDelet remote branch

On master branch

git commandsDescription
git merge devMerge dev into the master
git merge --no-ff -m “…” devMerge without fast forward mode
git merge origin/masterMerge into the remote origin/master branch

  1. Bug branch

git commandsDescription
git stashrecord the current state of the working directory and the index,
and go back to the clean HEAD.
git stash listshow the working directory
git stash applyrecover the working directory
git stash dropdelete the WIP(working in process)
git stash popequals apply + drop
  1. Cooperation

git commandsDescription
git remotecheck the remote repository status
git remote -vcheck the detailed information
git remote remove Remove the remote
git remote rename Rename the remote

August 16, 2018 06:04 PM

Get your imenu ready for modern Javascript

> Introduction

These days, I was working on a React Native project. In the meanwhile, I found it’s kind of hard to catch up the modern syntax of Javascript, so as for imenu (a built in project structure menu bar in Emacs).

Fortunately, there are so many people love Emacs and contribute to it. Thanks for Chen bin’s great post. I just put down more imenu generic expressions for modern Javascript like React, Vue. This helps me navigate and go through projects.

> Screenshot

A quick look a the result is here.

> Set up

Note: To get functions like componentDidMount, and exclude if, for, while, plain regexp in Emacs seems not working. At least I couldn’t find an easy solution like [^if|for|while]. But since imenu-generic-expression takes functions as parameters, I created another function to wrap one generic expression. Finally it works but as you can see, it’s not beautiful.

(defun my-js2-mode-hook ()
(progn
(setq imenu-create-index-function 'js2-imenu-make-index)))

(add-hook 'js2-mode-hook 'my-js2-mode-hook)

;; this imenu generic expression aims to exclude for, while, if when aims to match functions in
;; es6 js, e.g. ComponentDidMount(), render() function in React
;; https://emacs-china.org/t/topic/4538/7
(defun js-exception-imenu-generic-expression-regexp ()
;; (async)? xxx (e) { }
(if (re-search-backward "^[ \t]*\\(async\\)?[ \t]*\\([A-Za-z_$][A-Za-z0-9_$]+\\)[ \t]*([a-zA-Z0-9, ]*) *\{ *$" nil t)
(progn
(if (member (match-string 2) '("for" "if" "while" "switch"))
(js-exception-imenu-generic-expression-regexp)
t))
nil))

(defun js2-imenu-make-index ()
(interactive)
(save-excursion
;; (setq imenu-generic-expression '((nil "describe\\(\"\\(.+\\)\"" 1)))
(imenu--generic-function '(("describe" "\\s-*describe\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
("it" "\\s-*it\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
("test" "\\s-*test\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
("before" "\\s-*before\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
("after" "\\s-*after\\s-*(\\s-*[\"']\\(.+\\)[\"']\\s-*,.*" 1)
("Controller" "[. \t]controller([ \t]*['\"]\\([^'\"]+\\)" 1)
("Controller" "[. \t]controllerAs:[ \t]*['\"]\\([^'\"]+\\)" 1)
("Filter" "[. \t]filter([ \t]*['\"]\\([^'\"]+\\)" 1)
("State" "[. \t]state([ \t]*['\"]\\([^'\"]+\\)" 1)
("Factory" "[. \t]factory([ \t]*['\"]\\([^'\"]+\\)" 1)
("Service" "[. \t]service([ \t]*['\"]\\([^'\"]+\\)" 1)
("Module" "[. \t]module([ \t]*['\"]\\([a-zA-Z0-9_\.]+\\)" 1)
("ngRoute" "[. \t]when(\\(['\"][a-zA-Z0-9_\/]+['\"]\\)" 1)
("Directive" "[. \t]directive([ \t]*['\"]\\([^'\"]+\\)" 1)
("Event" "[. \t]\$on([ \t]*['\"]\\([^'\"]+\\)" 1)
("Config" "[. \t]config([ \t]*function *( *\\([^\)]+\\)" 1)
("Config" "[. \t]config([ \t]*\\[ *['\"]\\([^'\"]+\\)" 1)
("OnChange" "[ \t]*\$(['\"]\\([^'\"]*\\)['\"]).*\.change *( *" 1)
("OnClick" "[ \t]*\$([ \t]*['\"]\\([^'\"]*\\)['\"]).*\.click *( *" 1)
("Watch" "[. \t]\$watch( *['\"]\\([^'\"]+\\)" 1)

("Class" "^[ \t]*[0-9a-zA-Z_$ ]*[ \t]*class[ \t]*\\([a-zA-Z_$.]*\\)" 1)
("Class" "^[ \t]*\\(var\\|let\\|const\\)[ \t]*\\([0-9a-zA-Z_$.]+\\)[ \t]*=[ \t]*[a-zA-Z_$.]*.extend" 2)
("Class" "^[ \t]*cc\.\\(.+\\)[ \t]*=[ \t]*cc\..+\.extend" 1)

("Function" "\\(async\\)?[ \t]*function[ \t]+\\([a-zA-Z0-9_$.]+\\)[ \t]*(" 2) ;; (async)? function xxx (
("Function" "^[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*:[ \t]*\\(async\\)?[ \t]*function[ \t]*(" 1) ;; xxx : (async)? function (
("Function" "^[ \t]*\\(export\\)?[ \t]*\\(var\\|let\\|const\\)?[ \t]*\\([a-zA-Z0-9_$.]+\\)[ \t]*=[ \t]*\\(async\\)?[ \t]*function[ \t]*(" 3) ;; (export)? (var|let|const)? xxx = (async)? function (

;; {{ es6 beginning
("Function" js-exception-imenu-generic-expression-regexp 2) ;; (async)? xxx (e) { }
("Function" "^[ \t]*\\([A-Za-z_$][A-Za-z0-9_$.]*\\)[ \t]*:[ \t]*\\(async\\)?[ \t]*(" 1) ;; xxx : (async)? (
("Function" "^[ \t]*\\(export\\)?[ \t]*\\(var\\|let\\|const\\)?[ \t]*\\([A-Za-z_$][A-Za-z0-9_$.]*\\)[ \t]*=[ \t]*\\(async\\)?[ \t]*(" 3) ;; (export)? (var|let|const)? xxx = (async)? (
("Function" "^[ \t]*\\(export\\)?[ \t]*\\(var\\|let\\|const\\)?[ \t]*\\([A-Za-z_$][A-Za-z0-9_$.]*\\)[ \t]*=[ \t]*\\(async\\)?[ \t]*[A-Za-z_$][A-Za-z0-9_$.]*[ \t]*=>" 3) ;; (export)? (var|let|const)? xxx = (async)? e =>
;; }}

("Task" "[. \t]task([ \t]*['\"]\\([^'\"]+\\)" 1)))))

August 16, 2018 06:04 PM

Game theory: Solutions for others

This post contains solutions for other game theory problems.

Again, I don’t have much time putting down a lot of details here…

> Flip game II

  • Problem:

https://leetcode.com/problems/flip-game-ii/description/

  • Solution:
class Solution(object):
def canWin(self, s):
"""
:type s: str
:rtype: bool
"""
def search(s):
if s not in mem:
mem[s] = any(not search(s[:i] + '--' + s[i+2:]) for i in range(len(s)) if s[i:i+2] == '++')
return mem[s]
mem = {}
return search(s)

> A Chessboard Game

  • Problem:

https://www.hackerrank.com/challenges/a-chessboard-game-1/problem

  • Solution (Search):
n = int(input())
pos = []
for i in range(n):
arr = input().strip().split()
pos.append(tuple(int(i) for i in arr))


def search(x, y, dp, visited):
state = False
if visited[x][y] == True:
state = dp[x][y]
else:
if x-2 > 0 and y+1 < 16 and not search(x - 2, y + 1, dp, visited):
state = True
elif x-2 > 0 and y-1 > 0 and not search(x - 2, y - 1, dp, visited):
state = True
elif x+1 < 16 and y-2 > 0 and not search(x + 1, y - 2, dp, visited):
state = True
elif x-1 > 0 and y -2 > 0 and not search(x - 1, y - 2, dp, visited):
state = True
dp[x][y] = state
visited[x][y] = True
return dp[x][y]


visited = [[False] * 16 for _ in range(16)]
dp = [[False] * 16 for _ in range(16)]

rst = []
for x, y in pos:
rst.append(search(x, y, dp, visited))

for r in rst:
if r:
print("First")
else:
print("Second")

August 16, 2018 06:04 PM

Game theory: Solutions for coins in a line

> Solutions for tree coins in a line problem

This is a post for game theory problems. All solutions are written in Python.

I didn’t have to put a lot of details here. Comment below if you have any issue.

Keep in mind: the current state is generated by its sub states (further states).

> Coins in a line I

  • Problem: http://www.lintcode.com/en/problem/coins-in-a-line/

    This problem start taking coins from the right side.

  • Solution:

    1. DP
    class Solution:
    """
    @param n: an integer
    @return: a boolean which equals to True if the first player will win
    """
    def firstWillWin(self, n):
    dp = [False] * (n+1)

    for i in range(1, n+1):
    if not (dp[i-1] and dp[i-2]):
    dp[i] = True
    return dp[n]

dp[i] represents if the current player can win when i~n coins have been selected.

For not (dp[i-1] and dp[i-2]), dp[i] is True when and only when there is a False in dp[i]'s sub states dp[i-1] and dp[i-2]. Which means, there is a possible lose for his opponent. dp[i]'s sub states represent the coins his opponent can gain. We want this value smaller so that we can gain more.

  1. Search
class Solution:
def firstWillWin(self, n):
def search(i, dp, visited):
if visited[i]:
return dp[i]
if i == 0:
dp[i] = False
elif i == 1:
dp[i] = True
elif i == 2:
dp[i] = True
else:
dp[i] = not (search(i-1, dp, visited) and search(i-2, dp, visited))

visited[i] = True
return dp[i]

dp = [False] * (n+1)
visited = [False] * (n+1)
return search(n, dp, visited)

> Coins in a line II

  • Problem: http://www.lintcode.com/en/problem/coins-in-a-line-ii/

    This problem starts taking coins from the left side.

  • Solution:

    1. DP
    class Solution:
    """
    @param: values: a vector of integers
    @return: a boolean which equals to true if the first player will win
    """
    def firstWillWin(self, values):
    n = len(values)
    if n <= 2:
    return True
    dp = [0] * (n + 1)
    dp[n] = 0; dp[n-1] = values[n-1]; dp[n-2] = values[n-1] + values[n-2]

    sum = [0] * (n + 1)
    for i in range(n-1, -1, -1):
    sum[i] = sum[i+1] + values[i]

    for i in range(n-3, -1, -1):
    dp[i] = sum[i] - min(dp[i+1], dp[i+2])
    return dp[0] > sum[0] / 2

    dp[i] means the max coins can gain from i to end

    sum[i] means the sum from i to end

    dp[i] = max(values[i] + sum[i+1] - dp[i+1], values[i] + values[i+1] + sum[i+2] - dp[i+2]) => dp[i] = sum[i] - min(dp[i+1], dp[i+2])

    1. Search
    class Solution:
    """
    @param: values: a vector of integers
    @return: a boolean which equals to true if the first player will win
    """

    def firstWillWin(self, values):
    def search(i, dp, visited):
    if visited[i]:
    return dp[i]
    if i == n:
    dp[i] = 0
    elif i == n - 1:
    dp[i] = values[n - 1]
    elif i == n - 2:
    dp[i] = values[n - 1] + values[n - 2]
    else:
    dp[i] = self.sum[i] - min(search(i + 1, dp, visited), search(i + 2, dp, visited))

    visited[i] = True
    return dp[i]

    n = len(values)
    dp = [0] * (n + 1)
    visited = [False] * (n + 1)
    self.sum = [0] * (n + 1)
    for i in range(n - 1, -1, -1):
    self.sum[i] = self.sum[i + 1] + values[i]
    return search(0, dp, visited) > self.sum[0] / 2

> Coins in a line III

  • Problem:

    There are n coins in a line. Two players take turns to take a coin from one of the ends of the line until there are no more coins left. The player with the larger amount of money wins.

    Could you please decide the first player will win or lose?

  • Example

    Given array A = [3,2,2], return true.

    Given array A = [1,2,4], return true.

    Given array A = [1,20,4], return false.

  • Solution:

    1. DP
    class Solution:
    """
    @param: values: a vector of integers
    @return: a boolean which equals to true if the first player will win
    """
    def firstWillWin(self, values):
    n = len(values)
    dp = [[0] * (n+1) for _ in range(n+1)]

    ''' sum for array [i, j), i includes, j excludes '''
    sum = [0]
    for i in range(n):
    sum.append(sum[-1] + values[i])

    for i in range(n, -1, -1):
    for j in range(i+1, n+1):
    ''' initialization '''
    if i+1 == j:
    dp[i][j] = values[i]
    else:
    dp[i][j] = sum[j] - sum[i] - min(dp[i+1][j], dp[i][j-1])

    return dp[0][n] > sum[n] / 2

    dp[i][j]=max(values[i]+sum[i+1][j]-dp[i+1][j], values[j]+sum[i][j-1]-dp[i][j-1])

    values[i]+sum[i+1][j] and values[j]+sum[i][j-1] are equal to sum[i][j]

    So dp[i][j]=sum[i][j]-min(dp[i+1][j],dp[i][j-1])

    1. Search
    class Solution:
    """
    @param: values: a vector of integers
    @return: a boolean which equals to true if the first player will win
    """

    def firstWillWin(self, values):
    def search(start, end, sum, dp, visited):
    if visited[start][end]:
    return dp[start][end]
    elif start == end:
    dp[start][end] = sum[end] - sum[start-1]
    else:
    dp[start][end] = sum[end] - sum[start-1]\
    - min(search(start+1, end, sum, dp, visited), search(start, end-1, sum, dp, visited))

    visited[start][end] = True
    return dp[start][end]

    if not values:
    return False
    n = len(values)

    sum = [0] * (n+1)
    ''' sum for array [i, j], i includes, j includes '''
    for i in range(1, n+1):
    sum[i] = sum[i-1] + values[i-1]

    dp = [[0] * (n+1) for _ in range(n+1)]
    visited = [[False] * (n+1) for _ in range(n+1)]

    return search(1, n, sum, dp, visited) > sum[n] / 2

August 16, 2018 06:04 PM

Databases: you do not know

> Implicit and Explicit join p169

> Explicit Join

SELECT CourseName, TeacherName
From Courses INNER JOIN TEACHERS
ON Courses.TeacherID = Teachers.TeacherID

> Implicit Join

SELECT CourseName, TeacherName
FROM Courses, Teachers
WHERE Courses.TeacherID = Teachers.TeacherID

> Denormalized vs. Normalized Databases

Normalized databases are designed to minimize redundancy, while denormalized databases are designed to optimized read time.

In a traditional normalized database with data like Courses and Teachers, Courses might contain a column called TeacherID, which i a foreign key to Teacher. One benefit of this is that information about the teacher (name, address, etc.) is only stored once in the database. The drawback is that many common queries will require expensive joins.

Instead, we can denormalize the database by storing redundant data. For example, if we knew that we would have to repeat this query often, we might store the teacher’s name in the Courses table. Denormalization is commonly used to create highly scalable systems.

> Pros and Cons

Cons of DenormalizationPros of Denormalization
Updates and inserts are more expensive.Retrieving data is faster since we do fewer joins.
Denormalization can make update and insert code harder to write.Queries to retrieve can be simpler (and therefore less likely to have bugs), since we need to look at fewer tables.
Data maybe inconsistent. Which is the “correct” value for a piece of data?
Data redundancy necessitates more storage.

> Small Database Design

> Step 1: Handle Ambiguity

Database questions often have some ambiguity, intentionally or unintentionally. Before you proceed with your design, you must understand exactly what you need to design.

Imagine you are asked to design a system to represent an apartment rental agency. You will need to know whether this agency has multiple locations or just one. You should also discuss with your interviewer how general you should be. For example, it would be extremely rare for a person to rent two apartments in the same building. But does that mean you shouldn’t be able to handle that? Maybe, maybe not. Some very rare conditions might be best handled through a work around (like duplicating the person’s contact information in the database).

> Step 2: Define the Core Objects

Next, we should look at the core objects of our system. Each of these core objects typically translates into a table. In this case, our core objects might be Property, Building, Apartment, Tenant and Manager.

> Step 3

Outlining the core objects should give us a good sense of what the tables should be. How do these tables relate to each other? Are they many-to-many? One-to-many?

> Step 4

Finally, we fill in the details. Walk through the common actions that will be taken and understand how to store and retrieve the relevant data. We’ll need to handle lease terms, moving out, rent payments, etc. Each of these actions requires new tables and columns.

August 16, 2018 06:04 PM

C and C++: you do not know

Some basic knowledge of C and C++ in the book[1]. Well, I pick the title “you don’t know”. Precisely, it’s something I don’t know while you may already knew years ago. But it just sounds so stupid to named after “Java: I don’t know”…

> Pointers an References

  1. A pointer holds the address of a variable and can be used to perform any operation that could be directly done on the variable, such as accessing and modifying it.
  2. Note that the size of a pointer varies depending on the architecture: 32 bits on a 32-bit machine and 64 bits on a 64-bit machine.
  3. A reference is another name (an alias) for a pre-existing object and it does not have memory of its own. Unlike pointers, references cannot be null and cannot be reassigned to another piece of memory.

> Hash Table vs STL Map

  1. Since hash tables use the key to find the index that will store the value, an insert or loopup can be done in amortized O(1)
  2. A hash table is traditionally implemented with an array of linked lists, where each node in the linked list holds two pieces of data: the value and the original key.
    • We want to use a good hash function to ensure that the keys are well distributed.
    • No matter how good the hash function is, there are still collisions.
    • We may also wish to implement methods to dynamically increase or decrease the hash table size depending on capacity. For example, when the ratio of the number of elements to the table size exceeds a certain threshold, we may wish to increase the hash table size. This would mean creating a new hash table and transferring the entries from the old table to the new table. Because this is an expensive operation, we want to be careful to not do it too often.

> Q: How is a hash table implemented?

A: A hash table is traditionally implemented with an array of linked lists, where each node in the linked list holds two pieces of data: the value and the original key. When we want to insert a key value pair, we map the key to index in the array using a hash function. The value is then inserted into the linked list at that position.

Note that the elements in a linked list at a particular index of the array do not have the same key. Rather, hashFunction(key) is the same for these values.

hash table

In addition, we will want to note the following design criteria:

  1. We want to use a good hash function to ensure that the keys are well distributed. If they are not well distributed, then we would get a lot of collisions and the speed to find an element would decline.

  2. No matter how good the hash function is, we still have collisions, so we need a method for handling them, This often means chaining via a linked list, but it’s not the only way.

  3. We may also wish to implement methods to dynamically increase or decrease the hash table size depending on capacity. For example, when the ratio of the number of element to the table size exceeds a certain threshold, we may wish to increase the hash table size. This would mean creating a new hash table and transferring the entries from the old table to the new table. Because this is an expensive operation, we want to be careful to not do it too often.

> Virtual Functions

  1. A virtual function depends on a “vtable” or “Virtual Table”. A vtable is constructed which stores addresses of the virtual functions of this class. The compiler also adds a hidden vptr variable in all such classes which points to the vtable of that class.
  2. if a virtual functions is not overridden in the derived class, the vtable of of the derived class stores the address of the function in its parent class.
  3. The vtable is used to resolved the address of the function when the virtual functions is called.

> Shallow vs Deep Copy

  1. A shallow copy copies all the member values from one object to another. A deep copy does all this and also deep copies any pointer objects.
  2. One must also be careful with destructions of objects in a shallow copy.
  3. In real life, shallow copy is rarely used. Deep copy should be used in most cases, especially when the size of the copied structure is small.

> Volatile

  1. The key word volatile informs the compiler that the value of variable it it applied to can change from the outside, without any update done by the code.

  2. Declaration statement.

    int volatile xvolatile int x

> Virtual Base Class: Why does a destructor in base class need to be declared virtual?

  1. If destructor were not virtual, then Foo’s destructor would be called, even when p is really of type Bar.

    class Foo{}class Bar : public Foo{}Foo * p = new Bar()

  1. Cracking the Coding Interview, 6th Edition.

August 16, 2018 06:04 PM

A simple tweak to help you edit minified files in Emacs

Emacs “stucks” at editing long line files. It does but that’s not Emacs’s fault. Emacs has excellent gap buffer for large file editing. It’s due to the mode you apply to the file. These modes might freeze your Emacs when editing large file or minified files.

> Check Minified files

So here is a simple trick, I just check the first 30 line of the opened file. If first line is over 1000 in width, then it just enable fundamental-mode which works perfectly for these files.

;; if the first line is too long, enable fundamental by default
(defun get-nth-line-length (n)
"Length of the Nth line."
(save-excursion
(goto-char (point-min))
(if (zerop (forward-line (1- n)))
(- (line-end-position)
(line-beginning-position)))))
(defun spacemacs/check-minified-file ()
(and
(not (member (file-name-extension (buffer-file-name))
'("org" "md" "markdown" "txt" "rtf")))
(cl-loop for i from 1 to 30
if (> (spacemacs/get-nth-line-length i) 1000)
return t
finally return nil)))
(add-to-list 'magic-mode-alist (cons #'check-if-first-line-too-long 'fundamental-mode))

> Check Large File

This piece of code is from spacemacs, we have to set a couple variables. But you could have your own version.

(setq spacemacs-large-file-modes-list '(archive-mode tar-mode jka-compr git-commit-mode image-mode
doc-view-mode doc-view-mode-maybe ebrowse-tree-mode
pdf-view-mode))

(setq dotspacemacs-large-file-size 1)

;; check when opening large files - literal file open
(defun spacemacs/check-large-file ()
(let* ((filename (buffer-file-name))
(size (nth 7 (file-attributes filename))))
(when (and
(not (memq major-mode spacemacs-large-file-modes-list))
size (> size (* 1024 1024 dotspacemacs-large-file-size))
(y-or-n-p (format (concat "%s is a large file, open literally to "
"avoid performance issues?")
filename)))
(setq buffer-read-only t)
(buffer-disable-undo)
(fundamental-mode))))

;; Prompt to open file literally if large file.
(add-hook 'find-file-hook 'spacemacs/check-large-file)

August 16, 2018 06:04 PM

A complete solution for TinyURL (Leetcode System Design)

Note: The solution is translated from the Segmentfault post over here. Thanks for liuqi627.

> Question Description

Over here

> S: Scenario

Long URL to short URL and reversed.

> N: Need (Assume the system is not massive if you are not sure)

> QPS (queries per second)

  • Daily User: 100M
  • Daily usage per person: (Write) long2short 0.1, (Read) short2long 1
  • Daily request: Write 10M, Read 100M
  • QPS: Since a day is 86400s approximately 100K.

Write 100, Read 1K

  • Peak QPS: Write 200, Read 2K

(Thousand level can be handled by a single SSD MySQL Machine)

> Storage

  • 10M new mappings (long URL to short URL) per day
  • assume each mapping takes 100B in average
  • 1GB every day. 1 TB hard drive could stand for 3 years.

Storage is not the problem for this kind of system. Service like Netflix may have storage issues.

Through SN analysis, we could have a big picture of the system. In general, this system is not hard and could be handled by a single SSD Machine.

> A: API

Only one service: URLService

  • Core (Business Logic) Layer:
  • Class: URLService
  • Interface:
  • URLService.encode(String long_url)
  • URLService.decode(String short_url)
  • Web Layer:
  • REST API:
  • GET: /{short_url}, return a http redirect response(301)
  • POST: goo.gl method - google shorten URL

Request Body: {url=longUrl} e.g. {“longUrl”: “http://www.google.com/”}
Return OK(200), short_url is included in the data

> K: Data Access

> Step 1: Pick a storage structure

> SQL vs NoSQL?

  1. Does it need to support transactions? NoSQL does not support transaction.
  2. Do we need rich SQL query? NoSQL does not support as many queries as SQL.
  3. Pursue development efficiency? Most Web Framework supports SQL database very well (with ORM). It means fewer codes for the system.
  4. Do we need to use AUTO_INCREMENT ID? NoSQL couldn’t do this. It only has a global unique Object_id.
  5. Does the system has a high requirement for QPS? NoSQL has high performance. For example, Memcached’s QPS could reach million level, MondoDB does 10K level, MySQL only supports K level.
  6. How high is the system’s scalability? SQL requires developers write their codes to scale, while NoSQL comes with them (sharding, replica).

> Answer:

  1. No -> NoSQL
  2. No -> NoSQL
  3. Doesn’t matter because there are only a few codes. -> NoSQL
  4. Our algorithm needs AUTO_INCREMENT ID. -> SQL
  5. Write 200, Read 2K. Not high. -> SQL
  6. Not high. -> SQL

> System Algorithm

OK, let’s talk about the system algorithm. There are following solutions:

  1. Hash function:

    long_url -> md5/sha1

    • md5 convert a string into 128 binary bits, generally represented as 16 bytes hex:

    http://site.douban.com/chuan -> c93a360dc7f3eb093ab6e304db516653

    • sha1 convert a string into 160 binary bits, generally represented as 20 bytes hex:

    http://site.douban.com/chuan -> dff85871a72c73c3eae09e39ffe97aea63047094

These two algorithms could make sure hash values are randomly distributed, but the conflicts are inevitable. Any hash algorithm could have inevitable conflicts.

  • Pros: Simple. We could take the first 6 chars of the converted string.

  • Cons: Conflicts.

    Solutions: 1. use (long_url + timestamp) as the hash function key. 2. When conflicts, regenerates the hash value(it’s different because timestamp changes).

    Overall, when urls are over 1 billion, there would be a lot of conflicts and the efficiency could be very low.

  1. base62
    Take short_url as a 62 base notation. 6 bits could represent 62^6=57 billion.

Each short_url represent a decimal digit. It could be the auto_increment_id in SQL database.

public class URLService {
HashMap<String, Integer> ltos;
HashMap<Integer, String> stol;
static int COUNTER;
String elements;
URLService() {
ltos = new HashMap<String, Integer>();
stol = new HashMap<Integer, String>();
COUNTER = 1;
elements = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
}
public String longToShort(String url) {
String shorturl = base10ToBase62(COUNTER);
ltos.put(url, COUNTER);
stol.put(COUNTER, url);
COUNTER++;
return "http://tiny.url/" + shorturl;
}
public String shortToLong(String url) {
url = url.substring("http://tiny.url/".length());
int n = base62ToBase10(url);
return stol.get(n);
}

public int base62ToBase10(String s) {
int n = 0;
for (int i = 0; i < s.length(); i++) {
n = n * 62 + convert(s.charAt(i));
}
return n;

}
public int convert(char c) {
if (c >= '0' && c <= '9')
return c - '0';
if (c >= 'a' && c <= 'z') {
return c - 'a' + 10;
}
if (c >= 'A' && c <= 'Z') {
return c - 'A' + 36;
}
return -1;
}
public String base10ToBase62(int n) {
StringBuilder sb = new StringBuilder();
while (n != 0) {
sb.insert(0, elements.charAt(n % 62));
n /= 62;
}
while (sb.length() != 6) {
sb.insert(0, '0');
}
return sb.toString();
}
}

> Step 2: Database Schema

One table (id, long_url). id is the primary key, ordered by long_url

The basic system architecture:

Browser <-> Web <-> Core <-> DB

> O: optimize

> How to improve the response speed?

> Improve the response speed between web server and database

Use Memcached to improve response speed. When getting long_url, search in the cache first, then database. We could put 90% read request on the cache.

> Improve the response speed between web server and user’s browser

Different locations use different web server and cache server. All the areas share a DB used to match the users to the closest web server (through DNS) when they have a miss on the cache.

> What if we need one more MySQL machine?

> Issues:

  • running out of cache
  • More and more write requests
  • More and more cache misses

> Solutions:

Database Partitioning

  1. Vertical sharding 2. Horizontal sharding

The best way is horizontal sharding.

Currently table structure is (id, long_url). So, which column should be sharding key?

An easy way is id modulo sharding.

Here comes another question: How could multiple machines share a global auto_increment_id?

Two ways: 1. use one more machine to maintain the id. 2. use zookeeper. Both suck.

So, we do not use global auto_increment_id.

The pro way is put the sharding key as the first byte of the short_url.

Another way is to use consistent hashing to break the cycle into 62 pieces. It doesn’t matter how many pieces because there probably would not be over 62 machines (it could be 360 or whatever). Each machine is responsible for the service in the part of the cycle.

write long_url -> hash(long_url)%62 -> put long_url to the specific machine according to hash value -> generate short_url on this machine -> return short_url

short_url request -> get the sharding key (first byte of the short_url) -> search in the corresponding machine based on sharding key -> return long_url

Each time we add a new machine, put half of the range of the most used machine to the new machine.

> More Optimization

Put Chinese DB in China, American DB in the United States. Use geographical information as the sharding key, e.g. 0 for Chinese websites, 1 for American websites.

August 16, 2018 06:04 PM

为什么lisp,或者说common lisp现在这么冷门呢?

@JJPandari写道:

我能想到的因素:

  • 性能官网首页的benchmark显示它的web框架比node和ruby稍快。往前数十年硬件还很吃紧所以大家都用C/C++,最近才开始往C风格的语法里塞lisp?
  • 生态:python除了语法大家比较喜欢、研究方面库比较多之外,好像没什么优点了?但是大家都用它搞AI等等。它库丰富是没错,但是90年代刚出来的时候,为什么大家选择了给它写库,而不是common lisp或者别的呢?
  • 抽象能力/工程角度:比较高的上手难度和过于强大的宏能力可能是在工程方面比较不利的因素,可是最后别的语言发展来发展去,加lambda等等,都是向lisp靠拢,为什么宁可“实现一个漏洞百出的lisp解释器”,也不一步到位直接用lisp呢?真的是太难了没法招人,像Paul Graham说的“对手公司招Java程序员,不用管他,招Python程序员,这个公司还可以,招lisp程序员,你就要小心了”?

另外官网上推荐的emacs的cl配置叫slime,我仔细看了一下,跟那个史莱姆的拼写真的一模一样 :joy:

帖子: 31

参与者: 16

阅读整个主题

by @JJPandari JJPandari at August 16, 2018 03:56 PM

用 multiple-cursor 时 hungry-delete 这个包总会出奇怪的问题

@Roife写道:

之前和 counsel-find-file 起了冲突(删除路径时会出现问题)

现在又发现和 multiple-cursor 这个包不兼容(使用时无法删除字符)

只能果断卸载了

帖子: 4

参与者: 2

阅读整个主题

by @Roife Roife at August 16, 2018 03:34 PM

emacs27能不能在early-init.el里面判断emacs是否运行在terminal里面?

@lwczzhiwu写道:

emacs27加入了新特性,可以创建early-init.el,我在想有没有方法emacs加载的早期就判断emacs是否运行在X Window或者terminal中。

帖子: 28

参与者: 8

阅读整个主题

by @lwczzhiwu 碰碰车 at August 16, 2018 01:33 PM

大家怎样看待红芯所谓的国产内核?

@et2010写道:

这里面有什么套路吗?

看采访联合创始人说的也有点道理,没有必要重造一个轮子,但是这样和之前宣传的国产内核真的不矛盾吗?

帖子: 14

参与者: 11

阅读整个主题

by @et2010 et2010 at August 16, 2018 09:45 AM

spacemacs| SPC / (ag)报错error code 127

@stupidma写道:

长期VIM用户,刚开始尝试spacemacs,很多知识还不是很明白 系统:OS X 10.13.6 Emacs: GNU Emacs 26.1 Spacemacs: 最新的develop分支

使用VIM的时候,系统中安装了the silver search 2.2.0,在VIM中ag正常使用。

安装Spacemacs并使用默认设置后,每次调用SPC /(ag) 后,输入3个字符后就显示error code 127。使用网上的方法,安装exec-path-from-shell也不行,将系统中的$PATH清理后还是不行,实在是不知道怎么解决了。

希望将Emacs作用开发环境,能够实现方便的文件查找和函数定义调转、关键字搜索等。 希望能够得到社区的帮助,谢谢!

-添加信息-

$echo $PATH /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

/usr/local/bin中有一个ag 通过brew安装了the silver searcher ag:/usr/local/Cellar/the_silver_searcher/2.1.0/bin/

exec-path-from-shell的配置没有找到spacemacs的,按晚上的emacs的设置方法为,在dotspacemacs/user-init中加入了: (setq-default counsel-ag-base-command “/usr/local/Cellar/the_silver_searcher/2.1.0/bin/ag --vimgrep --nocolor --nogroup %s”)

帖子: 9

参与者: 4

阅读整个主题

by @stupidma Stupidma at August 16, 2018 09:23 AM

cedet-1.1 无法编译通过

@tangtutu写道:

for preload in cedet-compat; do
echo “(load “$preload”)” >> eieio-compile-script;
done; “emacs” -batch --no-site-file -l eieio-compile-script -f batch-byte-compile eieio.el eieio-comp.el eieio-opt.el eieio-custom.el eieio-doc.el eieio-base.el eieio-datadebug.el Loading cedet-compat…

In toplevel form: eieio.el:52:1:Warning: cl package required at runtime eieio.el:392:30:Warning: global/dynamic var `this’ lacks a prefix

In end of data: eieio.el:2990:1:Warning: the following functions might not be defined at runtime: eieio-copy-parents-into-subclass, eieio-add-new-slot, eieio-defmethod, eieio-set-defaults, eieio-eval-default-p, eieio-perform-slot-validation, eieio-default-eval-maybe, eieiomt-install, eieiomt-add, slot-unbound, object-class, eieio-slot-name-index, eieio-class-slot-name-index, slot-missing, object-class-fast, class-name, eieio-c3-merge-lists, eieio-class-precedence-dfs, eieio-class-precedence-c3, child-of-class-p, eieio-initarg-to-attribute, eieiomt-method-list, eieio-generic-form, eieio-list-prin1 eieio.el:2990:1:Warning: the function `cedet-edebug-add-print-override’ is not known to be defined. Wrote /home/tang/.emacs.d/plugins/cedet-1.1/eieio/eieio.elc

In byte-compile-file-form-defmethod: eieio-comp.el:95:30:Warning: reference to free variable bytecomp-outbuffer' eieio-comp.el:96:35:Warning: reference to free variableoutbuffer’

In end of data: eieio-comp.el:202:1:Warning: the following functions might not be defined at runtime: byte-compile-defmethod-param-convert, eieio-byte-compile-princ-code, byte-compile-compiled-obj-to-list eieio-comp.el:202:1:Warning: the following functions are not known to be defined: compiled-function-arglist, compiled-function-instructions, compiled-function-constants, compiled-function-stack-depth, compiled-function-doc-string, compiled-function-interactive, byte-compile-byte-code-maker Wrote /home/tang/.emacs.d/plugins/cedet-1.1/eieio/eieio-comp.elc

In eieio-browse: eieio-opt.el:49:20:Warning: Use `with-current-buffer’ rather than save-excursion+set-buffer

In eieio-describe-class: eieio-opt.el:87:23:Warning: cedet-called-interactively-p called with 0 arguments, but requires 1 eieio-opt.el:169:36:Warning: Use `with-current-buffer’ rather than save-excursion+set-buffer

In eieio-describe-generic: eieio-opt.el:344:23:Warning: cedet-called-interactively-p called with 0 arguments, but requires 1 eieio-opt.el:409:23:Warning: Use `with-current-buffer’ rather than save-excursion+set-buffer eieio-opt.el:718:13:Warning: Package assoc is obsolete!

In end of data: eieio-opt.el:813:1:Warning: the following functions might not be defined at runtime: speedbar-make-specialized-keymap, speedbar-add-expansion-list, speedbar-expand-line, speedbar-make-tag-line, speedbar-change-expand-button-char, speedbar-delete-subblock, speedbar-center-buffer-smartly, dframe-select-attached-frame, dframe-maybee-jump-to-attached-frame, speedbar-maybee-jump-to-attached-frame eieio-opt.el:813:1:Warning: the function `find-library-name’ is not known to be defined. Wrote /home/tang/.emacs.d/plugins/cedet-1.1/eieio/eieio-opt.elc

In toplevel form: eieio-custom.el:46:35:Error: Invalid function: object-class-fast

In eieiodoc-one-node: eieio-doc.el:118:15:Warning: reference to free variable indexstring' eieio-doc.el:130:56:Warning: reference to free variableroot-class’ eieio-doc.el:138:42:Warning: reference to free variable `rclass’ Wrote /home/tang/.emacs.d/plugins/cedet-1.1/eieio/eieio-doc.elc

In toplevel form: eieio-base.el:42:11:Error: Invalid function: object-class-fast Wrote /home/tang/.emacs.d/plugins/cedet-1.1/eieio/eieio-datadebug.elc Makefile:52: recipe for target ‘eieio’ failed make[1]: *** [eieio] Error 1 make[1]: Leaving directory ‘/home/tang/.emacs.d/plugins/cedet-1.1/eieio’ Makefile:87: recipe for target ‘eieio’ failed make: *** [eieio] Error 2

帖子: 1

参与者: 1

阅读整个主题

by @tangtutu tangtutu at August 16, 2018 09:15 AM

Melpa 又挂了

@LdBeth写道:

http://elpa.emacs-china.org/melpa/

似乎上游做了什么变动导致 packages list 刷不出来了。

帖子: 3

参与者: 2

阅读整个主题

by @LdBeth 好船 at August 16, 2018 04:39 AM

lsp-python如何设置checker?

@braineo写道:

最近在spacemacs下试用了一下lsp-python,速度不错UI也很漂亮。

但是有个不解的问题是,用anaconda的时候可以用flake8作为static checker,但是lsp mode是默认用lsp-ui作为checker的,而且默认只有pycodestyle。

好像也没有什么文档说明应该如何给lsp打开python-flake8,而我在pyls上看到说是支持flake8的。

我想问问大家是怎么设置pyls的

帖子: 7

参与者: 3

阅读整个主题

by @braineo Braineo at August 16, 2018 01:57 AM

August 15, 2018

";; This file is part of GNU Emacs."应该怎么用?

@ReimuXMX写道:

我发现 @tumashu 的posframe系列插件里的文件头部都有这句注释。

但是按我的理解posframe应该不是Emacs的一部分啊。

于是我翻了翻我的~/emacs.d/elpa/目录,却发现很多package的文件头都有这句注释,比如company-mode:

;;; company.el --- Modular text completion framework  -*- lexical-binding: t -*-

;; Copyright (C) 2009-2018  Free Software Foundation, Inc.

;; Author: Nikolaj Schumacher
;; Maintainer: Dmitry Gutov <dgutov@yandex.ru>
;; URL: http://company-mode.github.io/
;; Version: 0.9.6
;; Keywords: abbrev, convenience, matching
;; Package-Requires: ((emacs "24.3"))

;; This file is part of GNU Emacs.

;; ...

同时我见到flycheck的文件头的那句话就是;; This file is not part of GNU Emacs..

所以我迷糊了……这句注释代表了什么,应该怎么用?

=======UPDATE======

和GNU Elpa有关?

帖子: 3

参与者: 2

阅读整个主题

by @ReimuXMX 魔仙灵梦 at August 15, 2018 02:06 PM

发现一个emacs好玩的功能

@Matrix-I写道:

M-x zone

会启动emacs的一个屏保,目前看到了两种状态。

帖子: 10

参与者: 6

阅读整个主题

by @Matrix-I Matrix at August 15, 2018 11:50 AM

如何使用ivy-posframe 将ivy minibuffer魔改成 helm @tumashu

@Samray写道:

本打算通过ivy-posframeivy minibuffer 改成 helm-buffer 形式,不太喜欢 ivy 使用 minibuffer 总是从屏幕左下方弹来弹去,然后没发现 ivy-posframe有修改widthheight的变量,只好自己魔改源码

然后那个minibuffer没有找到适合window的宽,只能糙糙地用着,还有就是ivy 弹出的候选选项从 10改成 30,效果不完美,只限于能糙糙地用着的地步

@tumashu 求点建议

帖子: 3

参与者: 2

阅读整个主题

by @Samray Samray at August 15, 2018 08:56 AM

请问spacemacs怎么设置的换行符风格

@aladdinwang写道:

一般有

  • \r\n: windows
  • \n: unix
  • \r: 似乎是Linux?

我想启用unix的换行符风格,请问应该怎么设置?

另外将当前buffer的换行转换为unix风格的换行该用什么命令?

帖子: 7

参与者: 3

阅读整个主题

by @aladdinwang Wang, Enjun at August 15, 2018 08:52 AM

VS Code 1.26 的面包屑(Breadcrumbs)功能相当不错

@netjune写道:

文件和符号导航用非常方便, 比outline功能强几个数量级, 又省空间, emacs可以参考.

还有 Grid: Automated maximize of minimized editors, 自动把当前(焦点)窗口调大. 本来想写个插件在emacs上实现, 测试一下体验怎么样, 没想到vscode先实现了(emacs列表上看到有个人也在做这样的功能, 好像遇到一些emacs的限制, 没有进一步关注),

帖子: 19

参与者: 10

阅读整个主题

by @netjune Netjune at August 15, 2018 05:14 AM

August 14, 2018

你们的 emacs 启动多久了?

@jiacai2050写道:

image

看了下自己的,正好一个月了。

帖子: 4

参与者: 4

阅读整个主题

by @jiacai2050 Jiacai Liu at August 14, 2018 02:29 PM

emacs打开特殊文件特别卡

@ihaveadrame写道:

问题现象

emacs打开只有一行稍微大点(大概100多k)的文件会特别卡

使用profiler-start 和 profiler-report 调试结果

最初的文件格式为json,对应我配置的JavaScript-mode,后来为了尽可能减少自己配置影响 我转为text格式,还是一样的问题。

根据调试报告我找了很长时间原因,还是没能弄明白到底是哪个配置引起的问题。最后一根稻草,希望社区大牛能百忙中看下,即便给个思路也是极为感谢的。

帖子: 8

参与者: 7

阅读整个主题

by @ihaveadrame Alan at August 14, 2018 12:10 PM

ob-ipython:报错json-readtable-error 69

@yqu212写道:

ob-ipython里面运行ipython代码块时,会报错json-readtable-error。打开debug-on-error之后看到Debugger entered–Lisp error: (json-readtable-error . 69)。

在ob-ipython的issue里面找过。说是没有jupyter。可是打开后台进程可以看到jupyter已经启动。

有时把:session去掉会正常运行。有时又要把:session加上才行。多数时候只会报这个错。无法运行。摸不着头脑。

有谁知道这个问题是怎么回事吗?

附上系统信息:

  • OS: archlinux
  • Emacs: 27.0.50
  • Spacemacs: 0.300.0
  • Spacemacs branch: develop (rev. 6a724e416)

spacemacs以及所有包都是最新版本。

帖子: 8

参与者: 3

阅读整个主题

by @yqu212 yqu212 at August 14, 2018 11:09 AM

pandoc与ox-pandoc的使用区别?

@ispinfx写道:

有这样一个org文件:

#+TITLE: TITLE

* heading 1

inline \(a + b = 1\)

test 1

#+BEGIN_SRC latex :results drawer :exports results
  \begin{eqnarray}
    a + b = c
  \end{eqnarray}
#+END_SRC

test 2

#+begin_latex
\begin{eqnarray}
 i + j = k
\end{eqnarray}
#+end_latex

test 3

\begin{eqnarray}
x + y = z
\end{eqnarray}

the end.

如上的测试文件,在org下使用org-pandoc-export-to-markdown导出成markdown得到的文件是能正确导出几种不同写法公式的如下:

---
title: TITLE
---

# heading 1

inline $a + b = 1$

test 1

::: {.RESULTS .drawer}
$$\begin{eqnarray}
  a + b = c
\end{eqnarray} \qquad (1)$$
:::

test 2


$$\begin{eqnarray}
 i + j = k
\end{eqnarray} \qquad (2)$$

test 3

$$\begin{eqnarray}
x + y = z
\end{eqnarray} \qquad (3)$$

the end.

输入的提示说使用了如下参数:

Running pandoc with args: (-f org -t markdown -o a.md --atx-headers --wrap=preserve --standalone a.tmpOeWAA2.org)

但是,在命令行直接使用

pandoc -f org -t markdown -o a.md --atx-headers --wrap=preserve --standalone a.org

得到的文件却是

---
title: TITLE
---

# heading 1

inline $a + b = 1$

test 1

test 2

\begin{eqnarray}
 i + j = k
\end{eqnarray}

test 3

\begin{eqnarray}
x + y = z
\end{eqnarray}

the end.

无法正确转换公式。请问有谁知道如何在命令行下调用pandoc获得与在emacs里一样的输出吗?先谢过。

帖子: 2

参与者: 2

阅读整个主题

by @ispinfx displayname2 at August 14, 2018 10:25 AM

Elisp 有办法获取未经过 Advice 的原始的函数定义吗?

@lukertty写道:

比如说,

(define-advice switch-to-buffer (:after (&rest _) recenter) (recenter))

如何调用未advice的原始的 switch-to-buffer 呢?


问题有歧义,我重新编辑一下:

现在已知是 switch-to-buffer 已经被 Advice 了,可能是 around,也可能是别的其他的,这些函数会在实际调用 switch-to-buffer 的时候被调用。

那么现在我突然想调用最原始的 switch-to-buffer ,就只有依次 advice-remove 所有的 advice,然后调用,然后再加回去。

这种方法在advice非常多的时候不是很好用,而且不是很干净。

我就想问问,在这种情况下有没有办法去调用原始的 switch-to-buffer

帖子: 10

参与者: 5

阅读整个主题

by @lukertty Lukertty at August 14, 2018 09:46 AM

大家都是怎样使用Flycheck的?

@xshumeng写道:

在添加include搜索路径的时候,我是在LISP文件中直接写了一些项目的include绝对路径。

帖子: 12

参与者: 4

阅读整个主题

by @xshumeng 薛定饿 at August 14, 2018 01:38 AM

Emacs 在 iTerm2 下的按键支持

@canto写道:

由于经常需要通过 SSH 用 Emacs 修改代码, 有不能忍受 X11 低效率的 forward, 所以一直在寻找 iTerm 2 下对 Emacs 快捷键全支持的方法, 得以有幸在一个国外小哥的 GitHub 里找到了, 地址在此 choppsv1/ dot.spacemacs.d

和本主题相关的两个文件分别是 iterm-xterm-extra.el 以及 iterm-custom-keys.py

iterm-custom-keys.py 提供了生成 iTerm2 配置文件以及相应 keymap.el 文件的功能.

https://gist.github.com/Hirozy/b27b109f74eb5859479c351d9eb1b043 这个 Gist 提供了三个文件, 其中 iterm-custom-keys.py 修改了 “Text” 和 “Action” 字段, 具体修改内容可以看 Revisions .

在 Emacs 中加入 keymap, 将 json 文件放在~/Library/Application Support/iTerm2/DynamicProfiles 目录下, iTerm2 会自动识别^1, 然后使用新的 Profiles 创建并打开 Emacs, 诸如 C-; C-'等都可以使用了, 如果需要其它按键映射, 可以直接修改 iterm-custom-keys.py 文件

# 生成 keymap.el
python iterm-custom-keys.py > keymap.el
# 生成 iterm2.json
python iterm-custom-keys.py > ~/Library/Application Support/iTerm2/DynamicProfiles/iTerm2.json

关于终端下 Color 的问题, 可以使用 xterm-24bits, 具体讨论可见这里 True color (24-bit) in terminal , 已经可以和 GUI 做到几乎无差别的显示了.

多说一句, 对 macOS 提供 X11 支持的 XQuzrtz 可以直接支持众多快捷键, 不需要额外设置.

帖子: 4

参与者: 2

阅读整个主题

by @canto at August 14, 2018 12:40 AM

August 13, 2018

Aweshell 1.0 发布

@manateelazycat写道:

我一直用我自己的 MultiTerm在Emacs中执行终端命令, 最近看见大家都在折腾 EShell, 晚上花了一个小时写了一个 Aweshell

Aweshell 基于 eshell, 希望提供一个开箱即用的 eshell 使用环境, 下载下来就可以使用, 不用浪费时间折腾.

主要的增强功能有:

  1. 像 MultiTerm 一样对 eshell 进行多bufffer创建和切换功能
  2. 添加了一些方便的函数, 比如 clear buffer, toggle sudo , 感谢 @Samray
  3. 默认集成 eshell-prompt-extras.el , 提供长路径缩写, git分支, 远程shell等状态增强, 类似oh-my-zsh的效果
  4. 默认集成 esh-autosuggest.el , 提供类似 Fish 的历史命令补全功能, 包括对 bash/zsh 历史的补全
  5. 实时检查命令是否有效, 并对无效命令/别名提前进行高亮显示, 避免执行后发现敲错字符, 感谢 @casouri
  6. eshell更改目录的时候, 同步更新 buffer name, 感谢 @casouri
  7. 通过集成 exec-path-from-shell.el 来修复Mac下 eshell 报 “Command not found” 的错误, 主要是 /usr/local/bin/ 等路径没有导入 eshell path
  8. 内置一些方便的别名: f (find-file), fo (find-file-other-window), d (dired), ll (list files)
  9. 添加 git 命令的补全支持

默认按键:

  1. Ctrl + L : aweshell-clear-buffer
  2. Ctrl + Shift + L: aweshell-sudo-toggle
  3. Ctrl + H: company-complete-selection

以上按键均可通过以下选项进行自定义:

aweshell-complete-selection-key
aweshell-clear-buffer-key
aweshell-sudo-toggle-key

Aweshell 的多buffer管理的代码移植至我的 MultiTerm, 其他的大部分功能都是从 折腾eshell 这个帖子中集成的.

感谢 @Samray @casouri , 抄了你们的一部分代码, 很好用.

如果大家有兴趣, 可以一起向 aweshell.el 贡献代码, 我们折腾好了, 后人直接用就可以了.

安装方法见: https://github.com/manateelazycat/aweshell

安装完毕后, 直接绑定按键到下面三个命令就可以使用了:

aweshell-new
aweshell-next
aweshell-prev

帖子: 69

参与者: 17

阅读整个主题

by @manateelazycat Andy Stewart at August 13, 2018 06:47 PM

有人买manjaro 社区做的笔记本电脑吗?

@ziyuanjun写道:

最近想买新电脑,未找到合适的,发现manjaro社区在卖,不知道这台怎么样?大家能给指点一下吗?

帖子: 4

参与者: 3

阅读整个主题

by @ziyuanjun Ziyuanjun at August 13, 2018 03:38 PM

如何找到paredit-kill的end,但不执行kill?

@JJPandari写道:

我想要一个函数,它给出paredit-kill的end。

我想把它用作evil的text object,效果是:找到这个函数后我把evil-operator-map按键定为L,这样在normal-state下,我按下d L的效果和paredit-kill一样,y L可以复制当前point到paredit-kill将会kill到的point(但不会进行任何kill)。

我看了下paredit-kill里面是cond里各种kill,没有能给出kill终点的函数。另外有个paredit-point-at-sexp-end,但它只是简单用了forward-sexp等等,只能对lisp代码使用,不如paredit-kill智能。

帖子: 4

参与者: 2

阅读整个主题

by @JJPandari JJPandari at August 13, 2018 08:04 AM

ccls与cquery

@yicao写道:

c++补全的lsp server,ccls与cquery哪个更好用呢,补全速度,补全准确度方面. 一直都是用cquery,也有尝试一段时间vscode 的cpptool.同样的工程,都是用c_cpp_properties.json作为配置文件, vscode的补全就又快又准确.而cquery却补全很慢,而且有的无法补全. 打算试试ccls,不知道ccls的补全能力有没有vscode的好呢.微软确实是厉害啊,补全快,还准确,对于无法补全的,还能做到提示,将不能找到的头文件路径添加进c_cpp_properties.json配置文件,实时的添加头文件路径,而cuqery貌似只能是重启emacs重新解析配置文件.

帖子: 3

参与者: 2

阅读整个主题

by @yicao yicao at August 13, 2018 04:37 AM

August 12, 2018

上周一直在犯蠢,今天用`clang++ -MJ`生成了编译数据库,能工作了。

@glgl-schemer写道:

原本是关于windows下给cmake传递路径名的主题,现在改成抱怨贴。

这段时间在各种平台下配置写C++代码的环境,服务器上,自己笔记本,和一台win7的工作站。

先是服务器,本来服务器用的ycmd,用.py当项目配置文件,不过体验不是很好,flycheck是错的,开头报一个错,后面的错都报不出来,补全也补不出来。不过好歹能跳转到对应头文件(在另一个项目,用json索引的),跳转过去后提供的功能基本正常。

之前想写一个elisp脚本,需要读clang的json文件,由于以前用cquery-file-info写过,就把配置换成了cquery,然而cquery配置好了报一大堆错,理由是找不到头文件,不过cquery-file-info确实有头文件所在的路径。

不过我前几天得到了一台win7的工作站,就想着在工作站上写C++,于是就在工作站上装了MinGW,不过build cquery时有个thrid party报错了,于是把目光转向了irony。然后,我又尝试了一下那个存在include path在外部的项目,参数通过type nul | clang ... -E -v -都没问题,M-x irony-cdb-menu显示的命令行也是对的,不过表现和服务器上的cquery一样。。。

最后还是只有用自己笔记本(索引用的cquery),因为所有包全系统目录的,头文件找不到之类的问题不存在。。。不过也不是完美的,那个项目会在某些头文件报unknown typename 'namespace',不知道怎么回事。不过代码传到服务器上能build,本机就没试了,比较慢。

这种还挺好用的,适合我这种不用构建工具的奇葩。。。

帖子: 5

参与者: 3

阅读整个主题

by @glgl-schemer at August 12, 2018 07:51 AM

August 11, 2018

Hydra 是个好东西

@Roife写道:

感觉有点像 Vim 中的 ”模式“ 的概念,不过是可以自定义的

帖子: 4

参与者: 4

阅读整个主题

by @Roife Roife at August 11, 2018 05:39 PM

python 定义函数时加上 type hint,不会被识别了。

@Nasy写道:

这两天,我改了改习惯,把 Python 的代码加上 type hint 之后,我发现了一个问题,自动补全的时候,不会被识别为函数了,当然 eldoc 也用不了了…无论是 anaconda,还是用 lsp 都这样…

如图

不知道是个例,还是原来就这样?(突然后悔完全把原来的配置删掉)

帖子: 26

参与者: 5

阅读整个主题

by @Nasy Nasy at August 11, 2018 03:16 PM