Vim 常用命令

进入vim的命令

vim filename            #打开或新建文件,并将光标置于第一行首
vim +n filename         #打开文件,并将光标置于第n行首
vim + filename          #打开文件,并将光标置于最后一行首
vim +/pattern filename  #打开文件,并将光标置于第一个与pattern匹配的串处
vim -r filename         #在上次正用vim编辑时发生系统崩溃,恢复filename
vim filename1 filename2 #打开多个文件,依次编辑

移动光标类命令

h         #光标左移一个字符
l         #光标右移一个字符
space     #光标右移一个字符
Backspace #光标左移一个字符
k或Ctrl+p #光标上移一行
j或Ctrl+n #光标下移一行
Enter     #光标下移一行
w或W      #光标右移一个字至字首
b或B      #光标左移一个字至字首
e或E      #光标右移一个字j至字尾
)         #光标移至句尾
(         #光标移至句首
}         #光标移至段落开头
{         #光标移至段落结尾
nG        #光标移至第n行首
n+        #光标下移n行
n-        #光标上移n行
n$        #光标移至第n行尾
H         #光标移至屏幕顶行
M         #光标移至屏幕中间行
L         #光标移至屏幕最后行
0         #注意是数字零, 光标移至当前行首
$         #光标移至当前行尾

屏幕翻滚类命令

Ctrl+u    #向文件首翻半屏
Ctrl+d    #向文件尾翻半屏
Ctrl+f    #向文件尾翻一屏
Ctrl+b   #向文件首翻一屏
nz        #将第n行滚至屏幕顶部,不指定n时将当前行滚至屏幕顶部。

插入文本类命令

i         #在光标前
I         #在当前行首
a         #光标后
A         #在当前行尾
o         #在当前行之下新开一行
O         #在当前行之上新开一行
r         #替换当前字符
R         #替换当前字符及其后的字符,直至按ESC键
s         #从当前光标位置处开始,以输入的文本替代指定数目的字符
S         #删除指定数目的行,并以所输入文本代替之
ncw或nCW  #修改指定数目的字
nCC       #修改指定数目的行

复制剪切粘贴

# v #切换到 VISUAL 模式, 移动光标选择文本
c         #替换(Change)
d         #删除(Delete)
y         #复制(“Yank”)
yy        #复制当前行
p         #粘贴
.         #重复最后一次操作

删除命令

ndw或ndW  #删除光标处开始及其后的n-1个字
do        #删至行首
d$        #删至行尾
ndd       #删除当前行及其后n-1行
x或X      #删除一个字符,x删除光标后的,而X删除光标前的
Ctrl+u    #删除输入方式下所输入的文本

搜索及替换命令

/pattern  #从光标开始处向文件尾搜索pattern
?pattern  #从光标开始处向文件首搜索pattern
n         #在同一方向重复上一次搜索命令
N         #在反方向上重复上一次搜索命令
:s/p1/p2/g       #将当前行中所有p1均用p2替代
:n1,n2s/p1/p2/g  #将第n1至n2行中所有p1均用p2替代
:g/p1/s//p2/g    #将文件中所有p1均用p2替换

选项设置

all        #列出所有选项设置情况
term       #设置终端类型
ignorance  #在搜索中忽略大小写
list       #显示制表位(Ctrl+I)和行尾标志($)
number     #显示行号
nonumber   #隐藏行号
report     #显示由面向行的命令修改过的数目
terse      #显示简短的警告信息
warn       #在转到别的文件时若没保存当前文件则显示NO write信息
nomagic    #允许在搜索模式中,使用前面不带“\”的特殊字符
nowrapscan #禁止vim在搜索到达文件两端时,又从另一端开始
mesg       #允许vim显示其他用户用write写到自己终端上的信息

最后行方式命令

:n1,n2 co n3 #将n1行到n2行之间的内容拷贝到第n3行下
:n1,n2 m n3  #将n1行到n2行之间的内容移至到第n3行下
:n1,n2 d     #将n1行到n2行之间的内容删除
:w           #保存当前文件
:e filename  #打开文件filename进行编辑
:q           #退出vim
:q!          #不保存文件并退出vim
:!command    #执行shell命令command
:n1,n2 w!command #将文件中n1行至n2行的内容作为command的输入并执行之,若不指定n1,n2,则表示将整个文件内容作为command的输入
:r!command   #将命令command的输出结果放到当前行 。
Posted in Linux, Tips | Tagged | 1 Comment

正则表达式的贪婪与非贪婪模式

在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 "dxxxdxxxd",举例如下:

(d)(\w+)
"\w+" 将匹配第一个 "d" 之后的所有字符 "xxxdxxxd"

(d)(\w+)(d)
"\w+" 将匹配第一个 "d" 和最后一个 "d" 之间的所有字符 "xxxdxxx"。虽然 "\w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功,"\w+" 可以 "让出" 它本来能够匹配的最后一个 "d"

由此可见,"\w+" 在匹配的时候,总是尽可能多的匹配符合它规则的字符。虽然第二个举例中,它没有匹配最后一个 "d",但那也是为了让整个表达式能够匹配成功。同理,带 "*" 和 "{m,n}" 的表达式都是尽可能地多匹配,带 "?" 的表达式在可匹配可不匹配的时候,也是尽可能的 "要匹配"。这种匹配原则就叫作 "贪婪" 模式 。

非贪婪模式:

在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。举例如下,针对文本 "dxxxdxxxd" 举例:

(d)(\w+?)
"\w+?" 将尽可能少的匹配第一个 "d" 之后的字符,结果是:"\w+?" 只匹配了一个 "x"

(d)(\w+?)(d)
为了让整个表达式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配,从而使整个表达式匹配成功。因此,结果是:"\w+?" 匹配 "xxx"

更多的情况,举例如下:

举例1:表达式 "<td>(.*)</td>" 与字符串 "<td><p>aa</p></td> <td><p>bb</p></td>" 匹配时,匹配的结果是:成功;匹配到的内容是 "<td><p>aa</p></td> <td><p>bb</p></td>" 整个字符串, 表达式中的 "</td>" 将与字符串中最后一个 "</td>" 匹配。

举例2:相比之下,表达式 "<td>(.*?)</td>" 匹配举例1中同样的字符串时,将只得到 "<td><p>aa</p></td>", 再次匹配下一个时,可以得到第二个 "<td><p>bb</p></td>"。

Posted in JavaScritp, PHP, Tips | Leave a comment

巧用用户工具强化你的 Editplus

Editplus 的 "用户工具" 功能允许用户通过 Editplus 来运行自己指定的命令, 而且还有专用快捷键更快捷的执行它.

通过一个实际的例子来理解一下什么是 "用户工具" 功能:

1, 工具->参数 #打开参数设置对话框
2, 工具->用户工具->添加工具->程序 #添加一个新的用户工具
3, 在"菜单文本"文本框中输入"SHOW-IP"
   在"命令"文本框中输入"ipconfig"
   勾选上"捕获输出"复选框
4, 应用->确定 #保存设置
5, 工具->SHOW-IP #执行用户命令

怎么样? 看到效果了没, 在 Editplus 文本编辑区下面出现了输出窗口, 输出窗口中显示了 ipconfig 命令执行的返回值, 它就和 "开始->运行->cmd->ipconfig" 的效果一下.

上面的例子能帮助我们理解 "用户工具" 功能, 但好像不实用, 我们再来玩一个实用性强一点儿的:
我们将要写一个 Math 工具, 它要实现的功能是将计算出我们在 Editplus 编辑区选中的数学表达式的运算结果. 它将利用到 php.exe (http://www.php.net/)
准备工作, 我们将 php.exe 的安装目录放到环境变量中去:

1, 假设我们 php.exe 的安装目录是 "D:\Program Files\EasyPHP-5.3.2i\php"
2, 我的电脑->右键->属性->高级->环境变量->系统变量下的"Path"->编辑->在"变量值"中添加";D:\Program Files\EasyPHP-5.3.2i\php"->确定->确定->确定

我们开始设置 Math 功能:

1, 新建 math.php 保存(例如保存在 F:\software\editplus_config\editplus_tool\math.php) , 文本编码要是 ANSI.
2, 编辑 math.php 内容: <?php $argv[1]=="" ? exit("error!") : eval('echo $t = '.$argv[1].';'); ?>
3, Editplus->工具->参数
4, 工具->用户工具->添加工具->程序
5, 在"菜单文本"文本框中输入"Math"
   在"命令"文本框中输入"php"
   在"参数"文本框中输入"F:\software\editplus_config\editplus_tool\math.php $(CurSel)"
   勾选上"捕获输出"复选框
6, 应用->确定
7, 新建一个空白文档, 输入 "1+2+3", 选中输入的文字, 工具->Math, 在输出窗口中会出现运算结果. 成功了! 感觉还不错吧. ^__^

前面《一劳永逸的 Editplus 配置》文章中介绍的小技巧 "EditPlus 集成 SVN" 也是同样利用了 "用户工具" 来实现的.

#常用参数变量:
$(FilePath)      //文件路径
$(FileDir)       //文件目录
$(FileName)      //文件名称
$(FileNameNoExt) //文件名称(无扩展名)
$(FileExt)       //文件扩展名
$(FilePathNoDrv) //文件路径(无驱动器名称)
$(ProjectName)   //工程名称
$(AppDir)        //应用程序目录
$(CurLine)       //当前行号
$(CurCol)        //当前列号
$(CurSel)        //当前选定区域
$(CurWord)       //当前单词
$(Copy)          //复制选定文本
$(WindowList)    //窗口列表
$(Prompt)        //提示用户输入自定义参数

#常用起始目录变量:
$(FileDir)       //文件目录
$(DirWin)        //windows目录
Posted in PHP, Tips, Tool | Tagged , , | Leave a comment

微博缩短网址的实现

原文在这里

随着类似Twitter的微型博客网站的出现,由于字符数的限制,网址缩短服务日渐增多。加上网址缩短服务提供商提供网址追踪等服务,这一业务日渐兴起。知名网址缩短服务商Bit.ly的主要业务便是为微博Twitter提供网址缩短服务。 比如sina微博的sinaurl.cn,腾讯微博的url.cn等。

实现原理很简单,主要是将用户提交的 url 地址转化成一个唯一的字串,这个字串就对应着真实的 url,怎么样实现这种转换呢?

url 的转换摘自:http://www.cnblogs.com/sunli/archive/2010/03/25/1696183.html

数据库只有两个字段seq(自增长数字)和url(数字的url地址,建立索引)。

用户输入一个url地址,查询表是否包含此url,如果存在,则返回seq的数字,

如果不存在,则插入数据库,得到一个新增加的自增seq数字,为了缩短数字占用的字符数,我们可以把abc等字母的大小写用上。这样10个数字,26个小写字母,26个大小字母就组成了一个62进制了。比如数字10000000000(100亿)转换后就是aUKYOA,只有6位了,这样就能缩短很多的网址了。

<?php
//十进制转到其他制
function dec2any( $num, $base=62, $index=false ) {
    if (! $base ) {
        $base = strlen( $index );
    } else if (! $index ) {
        $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" ,0 ,$base );
    }
    $out = "";
    for ( $t = floor( log10( $num ) / log10( $base ) ); $t >= 0; $t-- ) {
        $a = floor( $num / pow( $base, $t ) );
        $out = $out . substr( $index, $a, 1 );
        $num = $num - ( $a * pow( $base, $t ) );
    }
    return $out;
}

function any2dec( $num, $base=62, $index=false ) {
    if (! $base ) {
        $base = strlen( $index );
    } else if (! $index ) {
        $index = substr( "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", 0, $base );
    }
    $out = 0;
    $len = strlen( $num ) - 1;
    for ( $t = 0; $t <= $len; $t++ ) {
        $out = $out + strpos( $index, substr( $num, $t, 1 ) ) * pow( $base, $len - $t );
    }
    return $out;
}
?>

得到缩短的网址以后,怎样实现网址的转发呢?可以利用 ttserver,将缩短网缩字串当作key,真实的 url 地址当作 value,存入ttserver中。ttserver本身就提供 http 访问,只需要稍加修改就可以直接利用 ttserver 进行缩短网址的转发:

在 ttserver 源码目录下找到 ttserver.c 这个文件,这里我用的是 tokyotyrant-1.1.39 ,跳到第 2981 行,将下面的几行改成图中所示:

保存退出,编译安装 ttserver,网上有很多安装教程,可以参考。

启动 ttserver,并向里面写入一条 key 为 aaaaaa,value为 http://www.baidu.com 的值。

curl -X PUT http://127.0.0.10:11221/aaaaaa -d "http://www.baidu.com"

主要目的是用 http 访问 ttserver 时直接取得到真实的 url 并做转发。这样做很方便,但不安全,ttserver 的 http 还支持删除、修改、插入数据(当然也可以修改 ttserver 的 http 访问入口,屏蔽掉这几种操作)。负载均衡方面,可以通过添加多条 A 记录随机转发到不同的 ttserver 机器上,但这样每台机器上存放的数据必须相同,网上也有说过ttserver 存过千万左右的数据以后不太稳定。

利用 nginx 就能很好解决直接用 ttserver 的问题,用 nginx 过滤掉 http 访问 ttserver 的删除、修改、插入的操作,并为多台 ttserver 提供反向代理的功能。如下图所示:

安装 nginx,我这里采用的是 nginx-0.8.36.tar.gz。安装 nginx 请参考:http://blog.s135.com/nginx_php_v6

打开 nginx.conf 配置文件:

#user  nobody;

#启动 8 个 nginx 进程
worker_processes  8;

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;

#pid        logs/nginx.pid;

events {
    # 用 epoll,最大连接数
    use epoll;
    worker_connections 65535;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    #tcp_nopush     on;

    # 由于只做转发,将超时时间设为 0
    keepalive_timeout  0;

    #gzip  on;
    # 反向代理 ttserver 1 号机,这里我放在一台机器上开了三个不同端口
    upstream backend_1 {
        server 127.0.0.10:11221 weight=5 max_fails=3 fail_timeout=1s;
    }
    # 反向代理 ttserver 2 号机
    upstream backend_2 {
        server 127.0.0.10:11221 weight=5 max_fails=3 fail_timeout=1s;
    }
    # 反向代理 ttserver 3 号机
    upstream backend_3 {
        server 127.0.0.10:11221 weight=5 max_fails=3 fail_timeout=1s;
    }

    server {
        listen       80;
        server_name  url.cn;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
        #当路径包含/count的时候,则代理到ttserver后端进行请求数据。
        #请注意,这里屏蔽了PUT,DELETE,POST方法,只是使用了GET,主要目的是为了安全性,
        #因为DELETE,POST,PUT是可以修改数据的
        location ~* /count(.*) {
            if ($request_method = PUT ) {
                return 403;
            }
            if ($request_method = DELETE ) {
                return 403;
            }
            if ($request_method = POST ) {
                return 403;
            }
            proxy_method GET;
        }

        #将以 a-z 为第一个字符的 url 代理到 ttserver 1 号机
        location ~* "^/([a-z]{1})([a-zA-Z0-9]{5})" {
            proxy_pass http://backend_1;
        }

        #将以 A-Z 为第一个字符的 url 代理到 ttserver 2 号机
        location ~* "^/([A-Z]{1})([a-zA-Z0-9]{5})" {
            proxy_pass http://backend_2;
        }

        #将以 0-9 为第一个字符的 url 代理到 ttserver 3 号机
        location ~* "^/([0-9]{1})([a-zA-Z0-9]{5})" {
            proxy_pass http://backend_3;
        }

        #error_page  404              /404.html;

        # redirect server error pages to the static page /50x.html
        #
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}

保存 nginx.conf 退出,现在就可以启动 ttserver了,我这里做演示,为了方便就在一台机器的三个端口启动了三个 ttserver。如图:

这里用 /ttserver/url_1 存放 ttserver 1号机的数据,依此类推,分别在 11222、11223启动 ttserver。

接着启动 nginx:

ulimit -SHn 65535
/usr/local/nginx/sbin/nginx

接着在服务器上用下面的命令插入测试数据:

curl -X PUT http://127.0.0.10:11221/aaaaaa -d "http://www.baidu.com"
curl -X PUT http://127.0.0.10:11222/Aaaaaa -d "http://www.soso.com"
curl -X PUT http://127.0.0.10:11223/1aaaaa -d "http://www.qq.com"

配置你机器的 hosts 指向 nginx 服务器:

127.0.0.10    url.cn

现在我们就可以打开浏览器,输入 http://url.cn/aaaaaa 就可以跳转到 baidu 上了,http://url.cn/Aaaaaa 就可以跳转到 soso 了,http://url.cn/1aaaaa 就可以跳转到 qq 上。至此配置完成,nginx只做转发工作,应付大规模的访问应该没什么问题,这也正是 nginx 所擅长的。ttserver 数据的取值操作也是很快的,在后面可以多开几台 ttserver,分散大量访问时的负载。

前台程序根据用户提交的 url 生成短的 url 后,根据前面的 nginx 分发规则写到某一台 ttserver 中,就可以了。nginx还支持一直 url hash 的均衡,但需要安装一个第三方模块ngx_http_upstream_hash_module,具体可以参考:http://blog.sina.com.cn/s/blog_5426e0180100dwsp.html

Posted in Apache, Linux, PHP, shell | Tagged , | Leave a comment

Python 入门

09年4月做的 Python 入门PPT, 介绍了 Python 的基本语法以及一些基本应用.

Posted in Python | Tagged | Leave a comment

VPS 自动备份数据库

1, 这是我的自动备份数据库 SHELL 脚本, 它将在 VPS 服务器上运行, 导出数据库后压缩成包, 然后通过 scp 命令将压缩包备份到另一台服务器( x4100 ) 中.

#!/bin/bash
D="/root/backup"
T=`date +%Y%m%d`
if [ ! -d "${D}/${T}" ]; then
	/bin/mkdir "${D}/${T}"
fi
/usr/local/mysql/bin/mysqldump --host=localhost --user=root --password=数据库密码 要备份的数据库名 > "${D}/${T}/${T}.sql"
cd ${D}
/bin/tar -czf  "${D}/${T}.tar.gz" "${T}"
/usr/bin/scp "${D}/${T}.tar.gz" kuco@x4100.unix-center.net:~/web_backup/studyday.net

2, 设置 Crontab , 更多的 crontab 介绍在这里

crontab -e
30 04 * * * /bin/sh /root/backup/web_backup.sh

3, 可能会遇到的问题:

在 STEP 1 中 scp 远程复制命令时会遇到输入密码的提示, 如果没有密码输入, 会导致复制不成功. 通过百度找到了解决的办法.

1, 在 VPS 服务器上的 ~/.ssh/ 目录下生成密钥文件:
mkdir -p ~/.ssh
ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa

2, 在 x4100 服务器上配置:
mkdir -p ~/.ssh
touch ~/.ssh/authorized_keys

3, 将 VPS 服务器的 ~/.ssh/id_rsa.pub 内容追加到 x4100 服务器的 ~/.ssh/authorized_keys 里面

这样就可能在调用 scp 命令时没有密码输入提示了.
Posted in Linux, Mysql, shell | Tagged , , | Leave a comment

计划任务 crontab 基本运用

Linux 计划任务 Crontab

基本格式:

*  *  *  *  *  command
分  时  日  月  周   命令

第1列表示分钟1~59 每分钟用*或者 */1表示
第2列表示小时1~23(0表示0点)
第3列表示日期1~31
第4列表示月份1~12
第5列标识号星期0~6(0表示星期天)
第6列要运行的命令

crontab文件的一些例子:

30 21 * * * /opt/lampp/lampp restart
#上面的例子表示每晚的21:30重启lampp。

45 4 1,10,22 * * /opt/lampp/lampp restart
#上面的例子表示每月1、10、22日的4 : 45重启lampp。

10 1 * * 6,0 /opt/lampp/lampp restart
#上面的例子表示每周六、周日的1 : 10重启lampp。

0,30 18-23 * * * /opt/lampp/lampp restart
#上面的例子表示在每天18 : 00至23 : 00之间每隔30分钟重启lampp。

0 23 * * 6 /opt/lampp/lampp restart
#上面的例子表示每星期六的11 : 00 pm重启lampp。

* */1 * * * /opt/lampp/lampp restart
#每一小时重启lampp

* 23-7/1 * * * /opt/lampp/lampp restart
#晚上11点到早上7点之间,每隔一小时重启lampp

0 11 4 * mon-wed /opt/lampp/lampp restart
#每月的4号与每周一到周三的11点重启lampp

0 4 1 jan * /opt/lampp/lampp restart
#一月一号的4点重启lampp

crontab 命令参数:

crontab -e : 新增/修改时程表
crontab -r : 删除目前的时程表
crontab -l : 列出目前的时程表
crontab file [-u user]-用指定的文件替代目前的crontab。
Posted in Linux, shell | Tagged , | Leave a comment

一劳永逸的 Editplus 配置

用习惯了 Editplus , 经常会做一些个性化的设置, 不仅让自己用得更顺手提高了工作效率, 也让自己节省了不少精力. 怎样才能让这些有用的配置不会因为重装系统而丢失呢?

默认情况下 Editplus 的配置文件(*.ini) 和 语法完成方成(*.acp) 以及语法着色文件(*.stx) 都是放在 Editplus 的安装目录下的. 要将它们分离出来做备份还是挺麻烦的.

还好聪明的 Editplus 给我们提供了一个有用的功能: 菜单->"工具"->"设置目录", 我们可以自定义 配置文件目录以及语法/着色/模版文件目录 的位置. 这样就可能在我们重新安装 Editplus 后将配置目录设置成我们自定义的目录就可以啦.

赶紧动手设置吧:
这里是我自用的配置文件: 下载

0, 假设我们 Editplus 的安装目录是:
   D:\Program Files\EditPlus 3\editplus.exe

1, 我们在安装目录外任意位置建好配置文件目录, 目录结构看上去像这样子:
   F:\software\editplus_config\
   F:\software\editplus_config\editplus_conf_1\
   F:\software\editplus_config\editplus_conf_2\
   F:\software\editplus_config\editplus_conf_ini\

   为什么会有 editplus_conf_1 和 editplus_conf_2 两个配置目录呢?
   因为我们可能会经常会遇到这样的情况:
   在我们在项目1中代码规范是这样子的
   function abc ()
   {
   }
   但在我们在项目2中代码规范是这样子的
   function abc () {
   }
   当我们经常在项目1和项目2中切换编写代码时, 我们设置的两个配置目录就可以派上用场啦,
   我们将项目1的语法文件放在 editplus_conf_1 目录中;
   我们将项目2的语法文件放在 editplus_conf_2 目录中;
   两个项目切换的时候只要修改一下 Editplus 的语法文件目录, 然后重新启动一下 Editplus 就OK啦.

2, 我们将 D:\Program Files\EditPlus 3\*.ini
   复制到 F:\software\editplus_config\editplus_conf_ini\

   我们将 D:\Program Files\EditPlus 3\*.stx, *.acp, template.*
   复制到 F:\software\editplus_config\editplus_conf_1\

3, 打开 Editplus 菜单->"工具"->"设置目录"
   将 ini 文件目录设置为 F:\software\editplus_config\editplus_conf_ini\
   将语法文件目录设置为 F:\software\editplus_config\editplus_conf_1\ 

4, 重启 Editplus , 新的配置目录就生效啦.

这样的方法可以将你的配置文件随身带着走啦~方便吧~~

应该注意的一些细节

设置好配置目录后, 有一个细节要注意一下:
打开 Editplus 菜单->"工具"->"参数"->"设置与语法" , 选择 "文件类型" 中的不同文件类型, 在下方的 "设置与语法" 页签中会有 "语法文件"/"自动完成" 两项, 注意: 这两项中都不能填写绝对路径 (带有盘符的路径), 只能填写相对应的配置文件名.

小技巧

EditPlus 集成 SVN  http://www.toplee.com/blog/615.html
1, 下载 sliksvn , 下载地址: http://www.sliksvn.com/en/download/
2, 将 tool.ini 存放在editplus的安装目录下
3, 启动editplus,CTRL+1 即可方便的提交
Posted in Tips, Tool | Tagged , | Leave a comment

将 VMware 最小化到系统托盘

VMware Workstation 最小化默认只能最小化到任务栏, 怎么样才能让它给我们腾出宝贵的任务栏空间, 让它最小化到系统托盘中去呢? Trayconizer 这个小软件能帮我们解决这个问题.

1, 下载 Trayconizer

官网地址: http://www.whitsoftdev.com/trayconizer/
下载地址: http://www.whitsoftdev.com/files/trayconizerw.zip

2, 解压 trayconizerw.zip

解压到任意目录, 压缩包里只有一个 exe 文件
我解压的位置是 D:\Program Files\trayconizerw\Trayconizer.exe

3, 创建 VMware 快捷方式(如果桌面上已经有 VMware 快捷了,可以跳过这一步)

找到 vmware 程序(我的安装位置是 D:\Program Files\VMware\VMware Workstation\vmware.exe ), 右键->发送到->桌面快捷方式

4, 修改 VMware 快捷方式

在桌面快捷方式上右键->属性->"快捷方式"页签->按下面的格式修改"目标"位置内容->应用->确定
"Trayconizer.exe的完整路径" "vmware.exe的完整路径"
注意: 因为 Trayconizer.exe / vmware.exe 路径中可能会有空格(就像"Program Files"这样的目录名), 所以要用双引号包起来.
      两个完整个路径之间要有一个空格符
例如: "D:\Program Files\trayconizerw\Trayconizer.exe" "D:\Program Files\VMware\VMware Workstation\vmware.exe"

5, 运行

双击修改后的快捷方式, 打开 vmware 窗口, 再按最小化..哈..看到效果了吧..它不会再待在任务栏里啦, 而是会自动最小化到系统托盘中去了.

不仅仅是 VMware Workstation , 其它的应用程序都可以用这样的办法来把它们最小化到系统托盘中去哟.

Posted in Tips, Tool | Tagged , | Leave a comment

细说 Javascript 函数

作者:F. Permadi
译者:Sheneyan(子乌)
时间:2006.01.03
英文原文: INTRODUCTION TO JavaScript Functions
子乌注:一篇相当不错的function入门文章,个人感觉相当经典。

词语翻译列表

function:函数(Function未翻译)
declare:定义
assign:指派,分配
functionbody:函数体(就是函数的内容)
object:对象
property:属性
unnamed:匿名(在这里没翻译成未命名)
object oriented programming:面向对象编程
class:类(比如后面的class data type我翻译成类数据类型)
pointer:指针
reassign:重新分配
nest:嵌套
feature:功能,特性
local/global:局部/全局
blueprint:蓝图(?)
user defined:用户自定义
instance:实例
prototype:原型(除了标题都不翻译)
internal:内部
constructor:构造器
duplication:复制

函数:定义
有以下这些方法可以定义一个函数。所有这些都是有效的,但是它们在后台如何实现的则有一些差别。

1, 常用的写法
一般大家都用这个写法来定义一个函数:
functionName([parameters]){functionBody};

Example D1:

function add(a, b){
    return a+b;
}
alert(add(1,2));    // 结果 3

当我们这么定义函数的时候,函数内容会被编译(但不会立即执行,除非我们去调用它)。而且,也许你不知道,当这个函数创建的时候有一个同名的对象也被创建。就我们的例子来说,我们现在有一个对象叫做“add”(要更深入了解,看底下函数:对象节。)

2. 匿名函数
我们也可以通过指派一个变量名给匿名函数的方式来定义它。

Example D2

var add = function(a, b) {
    return a+b;
}
alert(add(1,2));    // 结果 3

这个代码和前一个例子做了同样的事情。也许语法看起来比较奇怪,但它应该更能让你感觉到函数是一个对象,而且我们只是为这个对象指派了一个名称。可以把它看做和var myVar=[1,2,3]一样的语句。以这种方式声明的函数内容也一样会被编译。

当我们指派一个这样的函数的时候,我们并不一定要求必须是匿名函数。在这里,我作了和ExampleD2一样的事情,但我加了函数名“theAdd”,而且我可以通过调用函数名或者是那个变量来引用函数。

Example D2A

var add = function theAdd(a, b){
    return a+b;
}
alert(add(1,2));    // 结果 3
alert(theAdd(1,2)); // 结果也是 3

使用这种方式来定义函数在面向对象编程中是很有用的,因为我们能像底下这样使一个函数成为一个对象的属性。

var myObject = new Object();
myObject.add = function(a, b){return a+b};
// myObject 现在有一个叫做“add”的属性(或方法)
// 而且我可以象下面这样使用它
myObject.add(1, 2);

3, new
我们也可以通过使用运算符new来定义一个函数。
这是一个最少见的定义函数的方式并且并不推荐使用这种方式除非有特殊的理由(可能的理由见下)。语法如下:

varName = new Function([param1Name, param2Name,...paramNName], functionBody);

Example D3:

var add = new Function("a", "b", "return a+b;");
alert(add(3,4));    // 结果 7

我在这里有两个参数叫做a和b,而函数体返回a和b的和。请注意new Function(...)使用了大写F,而不是小写f。 这就告诉javascript,我们将要创建一个类型是Function的对象。 还要注意到,参数名和函数体都是作为字符串而被传递。我们可以随心所欲的增加参数,javascript知道函数体会是右括号前的最后一个字符串(如果没有参数,你可以只写函数体)。你没必要将所有东西都写在一行里(使用\或者使用字符串连接符+来分隔长代码)。\标记告诉JavaScript在下一行查找字符串的其余部分。例子如下:

Read More »

Posted in JavaScritp | Tagged | Leave a comment