VimScript学习笔记(3):补位映射(Operator-Pending Mappings)

这个Operator-Pending Mappings比较难翻译,字面意思是,一个操作要干什么,取决于后面跟的东西。比如g这个跳转命令,g后面跟个g就是跳到文章开头,如果跟个$就是跳到最后一个字符。本文说的Mappings,指的就是决定操作的后面的东西(movement)。可以这么想,这些命令后面需要跟一个变量,我们声明好这个变量(定义映射),然后用命令+变量的方式就可以调用了。

下面是一些类似命令的例子:

移动映射(Movement Mappings)

这个映射比较简单,和前面学到的映射没有很大区别。下面这个,将p映射为i((在括号之内的意思)。

测试:键入下面的文字。

将光标移到括号之内,输入dp,会发现括号之间的内容被删掉了。

使用u撤销删除,键入cp,发现进入了Insert Mode,可以修改括号之间的内容了。

再来一个,键入下面这个映射:

然后输入下面的测试文字:

在第一行输入命令db,发现函数体被删掉了。

定义一个移动映射的时候,可以参考下面这个步骤:

  1. 将光标移动到需要操作的文字开始的地方
  2. 进入可视模式(Visual Mode)
  3. 想办法将光标移动到你要操作的文字那里
  4. 结束,你要操作的文字已经选中了

其中,第3步就是你需要的操作,将这些操作映射到某个键就可以了。

映射开始的位置

上面这种方法有个不便之处,也许你已经发现了。就是每次我们执行命令的时候,都要将光标移动到要操作字符的开始位置,很不方便。

其实,我们可以定义选中文字的映射,然后通过命令来操作被选中的文字。此方法通过下面的例子学习。

键入下面这个命令:

测试,输入下面的文字:

光标移动到print上,键入cin(,会发现我们可以修改括号里面的内容,而不用将光标移动到括号内了。

<c-u>的作用在这里暂时忽略,不影响我们学习本章内容。

normal!的作用是,将后面的命令在Normal Mode下执行。为什么不直接写映射,要加这个呢。我试了一下,如果直接映射的话,Vim会作为连续的按键执行,执行到i可能就打断了,进入插入模式。

f(vi(比较好理解了,找到下一个括号,v进入Visual Mode,标记括号里面的内容。

至此,这个映射完成了选中文字的任务,剩下的就可以配合Vim命令处理了。

区别两种方式

上面这两种Operator-Pending的方法很好区分:

  • 如果映射最后选中的一部分文字,那么命令就会去操作选中的文字
  • 如果映射最后是跳到一个位置,那么命令就回去操作从光标原先的位置,到光标最后跳到的位置之间的文字

练习

MarkDown文本中,=======上面的文字会被视作标题。下面这个映射,选中了光标所在章节的标题。

测试,输入下面的文字。

在It…这一行,键入cih,会发现标题被替换掉了。

如果不能理解,可以参考这里

 

Django的数据迁移(Data migration)

Django支持ORM模型,我们不必写一条SQL语句,就可以方便使用面向对象管理数据库。数据库的管理可以分为结构迁移和数据迁移。

结构迁移是只是指表的结构改变。我们只需要修改Django的数据模型,然后用python manage.py makemigrations自动生成需要执行的数据迁移代码(一般保存在app/migrations文件夹下),然后用python manage.py migrate执行代码,就可以将变化应用到数据库。

另一种是数据迁移。之前我的做法是,写一个url映射到view,在view中写操作数据库的代码。执行完毕后删掉url。这样做有很多坏处:

  1. 将操作数据库开放了(即使可以写管理员权限)
  2. 污染url和view的代码
  3. 不能将所有有关数据库管理的代码放下migrations下面

好处是,如果常用的话,可以作为管理员“维护数据库”的一种方式。但如果是这种用途的话,还是写成一个中规中矩的view比较好。

其实,Django本身就有数据迁移的功能,上面这种做法太“歪门邪道”了。

数据迁移和结构迁移类似,只不过Django不是直接为你生成迁移结构的代码,而是生成一个框架,然后你在这个框架根绝自己的需要写代码。其实这个样子更灵活。

1.生成数据迁移的空白文件

执行下面的命令,生成一个迁移的脚本,等着你填上需要执行的命令。

生成的空白文件,如下所示。

2.填写数据迁移代码

文件中的Operations是空着的,这个地方是需要执行的数据迁移操作。数据操作可以写成函数,然后在Operations里面用RunPython运行函数。

函数的第一个变量是app,第二个是SchemaEditor,可以用来手动修改数据表的结构。不过不推荐这样做,做自动迁移的时候可能遇到问题。

下面这个迁移是自动根据以前名字的firstname和lastname生成name。导入模型的方式有点特殊,将要做的操作写到Python函数里面,然后在Operations里运行Python函数。除了RunPython之外,也可以RunSQL等等。

3.执行migrate命令,应用数据迁移

和应用结构迁移一样,执行下面的命令就可以了。

4.使用其他app里面的Model

如果RunPython函数里面用到别的app(不是此migrations存在的app)里面的model,应该在Dependencies里面模仿例子加上别的app的名字以及最新的migrations依赖。

否则,使用apps.get_model()的时候,会遇到LookupError: No installed app with label 'myappname'

下例,app1里面的migrations用到了app2的Model。

5.参考资料

  1. Django文档,Migrations
 

配置lisp开发环境

对lisp的支持,Emacs的是比较好,有Slime。后来,Vim也相应的出了Slimv,可能毕竟没有Emacs流行吧。一开始我的选择是Slimv,毕竟比较习惯vim了。但是安装这个插件遇到了很多问题。

对Vim的尝试

官方教程是直接下载插件放到vim目录下安装,我偷懒直接用Vundle从github安装的,结果运行出错。去google一下,发现这个项目下面有一个和我一模一样的错误:SlimvInitBuffer not defined。这是由于Vim对函数前缀b:的错误,之前的版本是直接忽略掉的,但是从vim7.4之后,就有问题了。参考这个issue,删掉所有的:b前缀就可以解决,因为其实:b什么都没有做。删掉是没有错误了,大还是我的REPL还是没有出现。

只好回到官方toturials上面了。发现上面说vim是需要pyhton-enable的,我去vim查看了一下版本,发现我的vim没有支持python,支持的是python3,只好重新编译安装。编译安装的过程可以参考这里。其实也可以不必重新安装,使用update-alternatives,可以直接将vim指定到python2.

花了很多时间之后,按照官方的教程下载,发现并没有启动,百般周折,最后还是选择了Racket。

最终选择Racket

Racket的前身是DrScheme(PLT-scheme?)现在plt-scheme的主页直接指向racket了。

安装方法是(ubuntu):

  1. 从https://download.racket-lang.org/ 下载安装脚本。
  2. chmod +x [下载到的脚本名字]
  3. sudo ./[脚本名字]

话说用111M的一个单文件sh,这么样的安装方式我还是第一次见……安装好之后,可以从ubuntu的GUI打开软件了。用官方的example试一下吧:

 

VimScript学习笔记(2):自动命令

1.Buffer-Local 设置和映射

Vim的设置和mapping都是可以针对窗口单独设置的,区别与全局设置。

创建两个文件,依次输入下命令:

测试一下,发现<leader>d<leader>x都能删除一行,映射成功。切换到另一个文件,就只有<leader>d能删除了,因为<leader>x映射前面有一个<buffer>,是“仅在当前Buffer里面生效的意思。

设置也可以针对Buffer单独设置。比如在起一个打开的文件中,输入:setlocal number!,会发现两个文件一个显示行号,另一个不显示。并不是所有的设置都支持:setlocal的,如果不支持,Vim就会自动使用:set命令设置全局来代替。具体那些命令支持,可以通过:helo setlocal查看。

此外,<leader>键也支持根据Buffer指定,前缀是<localleader>

2.自动命令

自动命令可以在某些事件发生的时候,自动触发一些命令。

举个例子,在Vim中新打开一个文件,直到我们执行:write命令之前,Vim是不会保存这个文件的,通过下面的自动命令,可以在每次打开一个新文件就保存一下。

这个命令的意思是,新建一个文件的时候,无论新建什么类型的文件,都先执行write命令。自动命令具体的结构如下:

“正则表达式”部分,可以让你指定在具体是什么事件发生的时候才触发。比如下面这条,就只会在新建txt文件的时候才自动写入。

下面这条命令,在自动打开html的时候会先格式化。

autocmd支持多重事件一起绑定,推荐的做法是,将“写入文件”与“读取文件”一起绑定。

nowrap的意思是,要不要自动换行。html文件可能存在比较长的单行,设置为nowrap有助于阅读。细节操作参考这里

在编程中,FileType是一个非常有用的事件。这个事件会在Vim设置Buffer的filetype的时候自动触发。比如,下面这两个命令设置了JavaScript和Python的快速注释。

设置之后,在JS中,按下<localleader>c,会在行首添加//,而在Python中,会在行首添加#

3.Buffer-Local的缩写

上文提到,set和map都是支持对Buffer单独设置的,事实上缩写也是支持的。输入下面这个命令:

然后输入:

会发现—被替换成了&mdash;

比较实用的地方,就是和FileType相结合,比如,我们可以针对不同的编程语言设置简写:

4.Autocommand Groups(自动命令组)

自动命令存允许重复绑定一个事件,也就是一个事件可以出发多个命令(废话),这里存在一个问题:我们无法对原来的命令解除绑定。也就是说,如果我们将自动命令写入了.vimrc文件,使用前文中介绍的<leader>sv快速应用.vimrc文件,那么.vimrc的命令会被再次绑定。

比如,将这个命令输入两次(效果等同与将这些命令写入.vimrc,然后执行:source $MYVIMRC两次):

然后写入文件。通过:messages,你会发现”Writing buffer!”被打印了两次。要知道.vimrc中算上插件绑定的命令可能有上千个,如果重复绑定,可能带来Vim反应慢,甚至出错等问题。

Vim对这个情况的处理方式是,对命令进行分组。使用分组组织命令的方式如下:

此时,如果再使用分组,定义命令的话:

……抱歉还是替换不了。这样做命令依然是重复绑定的,有人就是说,如果:write,那么在:messages里面你会看到 “Foo”, “Bar”, “baz”三个输出。

请注意,augroup并不会自动替换掉之前的命令。我们可以在augroup的第一个命令写autocmd!来删除。这个命令只会删除本组之前绑定过的命令。

推荐在.vimrc中所有的命令都使用分组,并且分组第一条为autocmd!.

5.关于多行命令

如果在.vimrc文件中写多行命令,直接换行就可以了。

如果在Vim的命令模式下写,需要在每一个句子的前面都加冒号。

但是如果你想将它们写到一行,可以使用|符号分割。比如,下面的这种形式。

 

搬砖感悟

最近年底了,职场上又有很多事情闹得沸沸扬扬。比如腾讯某部门年会出现的低俗活动,锤子某离职员工的吐槽等等,微信上也见有人说他们公司年会活动低俗之类的。

出现这种事情,挺让我震惊的,毕竟大公司,价值观应该是比较正的,竟然搞出这种事情来。其实,年会上这些“疯狂”的事情,归根结底是空虚的内心和工作得不到认同吧,要是一年都很忙,年底开个会,肯定正事都说不完。

虽然博主还没毕业,但是做到过的工作有七八份,兼职加全职。关于工作这件事,还是有点自己的想法的。

工作永远都做不完,做的开心最重要。现在我选择一份工作,最重要的是在这份工作中能学到多少东西。如果我认为一份工作是让我用自己的时间来换钱,做多长时间都不会有什么长进或者进步很慢的,我一定会毫不犹豫地辞职。

像程序员这种工作,我非常赞同只看结果。

因为就是有的人做得快,分配到的任务可能几个小时就写完了。有的人基础的东西要看很久。这时候做的又快又好的人下了班,做不完的人在加班,老板喜欢加班的人,那么老板八成是有病。所以我觉得上班时间学习是可以的,不加班是可以的,但是分配到的工作做不完,是不可以的。

公司文化、精神、价值观这种东西,都是耍流氓。我认为集体意识就是扯淡,文明的发展肯定是越来越强调个人的独立性,以前是这样,以后也肯定是这样。什么意思呢?要是公司的人自发都喜欢讨论技术,气氛很浓,这很好,要是公司大部分人都喜欢加班,不给加班费也自愿加班,也没啥问题。但是领导每天都号召大家加班,发扬某某精神,这就有问题了。请问你写到合同里面了吗?合同是六点下班,你要我加班,请问你给钱了吗?再说,工作都做完了,我在这里加班,你也得不到什么呀!要是我工作努力做都做不完,那你领导就要考虑一下分工的问题了。

所以嘛,对员工的要求都写到合同里面去,合同没写你还要我做,就不太好了。搞些什么价值观,这就没意思了,程序员又不是搞传销,代码又不知道他的组织是谁。

我看来,价值观这种东西纯粹就是忽悠人。借着价值观,就能搞一些不好意思明说的下贱勾当。以前在一个比较有名气的博客上看过,某博主在亚马逊上班的时候,想要用自己的博客宣传下公司,帮助公司招聘,他的上司不支持了,说:人们看你的博客,是因为你是一个独立的个体,如果你的立场不独立了,就失去他的价值了。后来这个博主到了淘宝,淘宝的上司却让他用博客给产品做广告,他不同意,结果上司就给他扣上了没有集体意识的帽子。我对个人的自由非常看重,如果公司让我做一件工作内容之外的事情,我没啥意见,但是公司逼我做,说你不做不行,那我肯定不乐意了。其实不光公司对员工有这种事情,也有很多员工占公司的便宜呐!比如用公司的打印机打印非办公的公司,去报销私人消费啦!本质上和加班没啥区别,都是要求契约之外的权益。肮脏得很呐!

说白了,就是我拿你的钱,给你做该做的工作。你要是对我好点,福利好点,那我工作就更认真一点,对得起你。但是我上班时间做什么,几点下班,你别管,我肯定能把工作完成就行。你别不乐意,不乐意你去找别人去,我找别的公司上班,就这样。都21世纪了,自由选择的权利肯定要有。

要是这么想,低俗年会就肯定不会发生了,除非你情我愿,那我没什么好说的。如果不是自愿的,那肯定一杯盐汽水泼到领导脸上,这尼玛什么鸡儿年会,老娘辞职!

不是自愿,又不想辞职,那只能低三下四任领导摆布。为什么会这样呢?还是不平等。工作就和谈恋爱一样,不平等了,才会有一些操蛋的事情发生。为什么不平等呢?因为你得到了一份和你能力不符合的工作,如果你辞职了,不能找到一份相当的工作。

所以啊,话又说回来,洒脱的资本还是个人的能力。做个程序员真好,付出就有回报,学到的东西就是你的。努力学习,发展自己,工作就谁的脸色都不用看。拿钱办事情,你尊重我我也尊重你,大家互利共赢,没必要妄自菲薄。

人生三分一的时间都在上班,要是上班就盼着下班,跟上课一样,那太折磨人了。不要做这样的工作,找工作的标准就是你上班的时候是不是想下班,要是想,那算了吧,太折磨人了。

新年了,祝你在新的一年,有一份不用盼着下班的工作!