在 QtCreator 使用 Fakevim 可以指定读取配置文件,在配置文件中映射按键,我发现当映射 + 寄存器时(也就是系统剪切板)不生效,比如下面这行命令:

1
map <Space>yy "+yy

尝试了很多方法,比如转义:\"+yy 等都不行,网上也搜不到相关问题,下载了 QtCreator 的源码后,分析 Fakevim 插件解析配置文件的部分,发现是一个 Bug,相关代码如下:

1
2
3
4
5
6
7
// qt-creator/src/plugins/fakevim/fakevimhandler.cpp
// bool FakeVimHandler::Private::handleExSourceCommand(const ExCommand &cmd)

// remove comment
int i = nextline.lastIndexOf('"');
if (i != -1)
nextline = nextline.remove(i, nextline.size() - i);

原来是判断 " 号是配置文件注释,将 " 号开始到结尾的部分给删除了,已经给 QtCreator 官方提了 Issue,说实话我也没想到修复这个问题的好方法。

另辟蹊径,既然要判断 " 号,而且代码里是判断最后一个 " 号的位置,那就给它加上个行内注释,让它不删除命令内容就行,比如还是上面的命令,修改后如下:

1
map <Space>yy "+yy " placehoder commend for a Fakevim parse bug

这样源码删除后面的注释后,剩下的就是原本想要执行的命令了,搞定 :)

参考并修正了其中的错误:https://www.cnblogs.com/malw/p/10542557.html

堆排序是基于完全二叉树实现的,在将一个数组调整成一个堆的时候,关键之一的是确定最后一个非叶子节点的序号,这个序号为 n/2-1n 为数组的长度。但是为什么呢?

可以分两种情况考虑:

  1. 堆的最后一个非叶子节点只有左孩子
  2. 堆的最后一个非叶子节点有左右两个孩子

完全二叉树的性质之一是:如果节点序号为 i,则它的左孩子序号为 2*i+1,右孩子序号为 2*i+2

  1. 对于 情况1 左孩子(最后一个元素)的序号为 n-1,则 n-1=2*i+1,推出 i=n/2-1
  2. 对于 情况2 左孩子(倒数第二个元素)的序号为 n-2,则 n-2=2*i+1,推出 i=(n-1)/2-1;右孩子(最后一个元素)的序号为 n-1,则 n-1=2*i+2,推出(这里跟左孩子推出的一样) i=(n-1)/2-1

很显然,当完全二叉树最后一个节点是其父节点的左孩子时,树的节点数(数组元素数)为偶数;当完全二叉树最后一个节点是其父节点的右孩子时(满二叉树),树的节点数(数组元素数)为奇数。

根据一般编程语言的特性,整数除不尽时向下取整,则若 n 为奇数时 (n-1)/2-1=n/2-1

因此对于 情况2 最后一个非叶子节点的序号也是 n/2-1

与 freedesktop.org 相关的软件

下面是一个与 freedesktop.org 相关的不完全软件列表。

你可以去我们的 Gitlab 服务查看和下载它们的代码、Bugs、提交合并请求。

freedesktop.org 本身并不每天运行这些项目:我们为自己运行项目的社区提供托管和基础设施。

All projects hosted by us are available under open-source licenses under equitable terms to all parties. These projects do not require Contributor License Agreements which assign more rights to one party than another. They may require an assertion like the Developer’s Certificate of Origin which is simply a more formal document to state that you are leally permitted to contribute under the project’s license; you do not, however, need to assign anyone rights that you do not yourself receive to others’ contributions.

桌面中间件和框架

这些项目提供了桌面的基础服务。

  • AccountsService 提供本地账户的信息。
  • D-Bus 是一个详细系统,提供了进程间和服务间通讯。
  • GeoClue 提供地理位置信息。
  • PolicyKit 是一个允许非特权应用配置和请求特权服务和接口的工具。
  • NetworkManager 允许应用发现,配置,连接有线和无线网络。
  • realmd 允许客户端发现,认证和加入网络(如 Active Directory)。
  • upower 提供了关于电源设备,如电池和充电状态的信息。
  • Zeitgeist 是一个桌面事件日志框架。

桌面规范和工具

这些规范和工具定义了跨桌面标准和互通性。

阅读全文 »

摘自 bash man 手册

字符 $ 引入了参数扩展,命令替换和算术扩展。要扩展的参数名或符号可能包含在花括号中,花括号可选的,但是可以使得要扩展的变量不会与紧随其后的字符合并,成为新的名称。

使用花括号的时候,匹配的右括号是第一个 },并且它没有被反斜杠引用或包含在一个引用的字符串中,也没有包含在一个嵌入的算术扩展,命令替换或是参数扩展中。

  • ${parameter}

    被替换为 parameter 的值。

    • 如果 parameter 是一个位置参数,并且数字多于一位时;或者当紧随 parameter 之后有不属于名称一部分的字符时,都必须加上花括号。
    • 如果 parameter 的第一个字符是一个感叹号,将引进一层间接变量。bash 使用以 parameter 的其余部分为名的变量的值作为变量的名称;接下来新的变量被扩展,它的值用在随后的替换当中,而不是使用 parameter 自身的值。这也称为 indirect expansion(间接扩展). 例外情况是下面讲到的 ${!prefix*}

下面的每种情况中,word 都要经过波浪线扩展,参数扩展,命令替换和算术扩展。如果不进行子字符串扩展,bash 测试一个没有定义或值为空的参数;忽略冒号的结果是只测试未定义的参数。

  • ${parameter:-word}

    Use Default Values(使用默认值)。如果 parameter 未定义或值为空,将替换为 word 的扩展。否则,将替换为 parameter 的值。

  • ${parameter:=word}

    Assign Default Values(赋默认值)。如果 parameter 未定义或值为空, word 的扩展将赋予 parameter. parameter 的值将被替换。位置参数和特殊参数不能用这种方式赋值。

  • ${parameter:?word}

    Display Error if Null or Unset(显示错误,如果未定义或值为空)。如果 parameter 未定义或值为空,word (或一条信息,如果 word 不存在) 的扩展将写入到标准错误;shell 如果不是交互的,则将退出。否则,parameter 的值将被替换。

  • ${parameter:+word}
    Use Alternate Value(使用可选值)。如果 parameter 未定义或值为空,不会进行替换;否则将替换为 word 扩展后的值。

  • ${parameter:offset}${parameter:offset:length}

    Substring Expansion(子字符串扩展)。扩展为 parameter 的最多 length 个字符,从 offset 指定的字符开始。

    • 如果忽略了 length,扩展为 parameter 的子字符串,从 offset 指定的字符串开始。length 和 offset 是算术表达式 (参见下面的 ARITHMETICEVALUATION 算术求值 段落)。length 必须是一个大于等于 0 的数值。
    • 如果 offset 求值结果小于 0,值将当作从 parameter 的值的末尾算起的偏移量。
    • 如果 parameter 是 @,结果是 length 个位置参数,从 offset 开始。
    • 如果 parameter 是一个数组名,以 @ 或 * 索引,结果是数组的 length 个成员,从 ${parameter[offset]} 开始。子字符串的下标是从 0 开始的,除非使用位置参数时,下标从 1 开始。
  • ${!prefix*}

    扩展为名称以 prefix 开始的变量名,以特殊变量 IFS 的第一个字符分隔。

  • ${#parameter}

    替换为 parameter 的值的长度 (字符数目)。

    • 如果 parameter 是 * 或者是 @, 替换的值是位置参数的个数。
    • 如果 parameter 是一个数组名,下标是 * 或者是 @, 替换的值是数组中元素的个数。
  • ${parameter#word}${parameter##word}

    word 被扩展为一个模式,就像路径扩展中一样。

    • 如果这个模式匹配 parameter 的值的起始,那么扩展的结果是将 parameter 扩展后的值中,最短的匹配 (``#’’ 的情况) 或者最长的匹配 (``##’’的情况) 删除的结果。
    • 如果 parameter 是 @ 或者是 *, 则模式删除操作将依次施用于每个位置参数,最后扩展为结果的列表。
    • 如果 parameter 是一个数组变量,下标是 @ 或者是 *, 模式删除将依次施用于数组中的每个成员,最后扩展为结果的列表。
  • ${parameter%word}${parameter%%word}

    word 被扩展为一个模式,就像路径扩展中一样。

    • 如果这个模式匹配 parameter 扩展后的值的尾部,那么扩展的结果是将 parameter 扩展后的值中,最短的匹配 (``%’’ 的情况) 或者最长的匹配 (``%%’’的情况) 删除的结果。
    • 如果 parameter 是 @ 或者是 *, 则模式删除操作将依次施用于每个位置参数,最后扩展为结果的列表。
    • 如果 parameter 是一个数组变量,下标是 @ 或者是 *, 模式删除将依次施用于数组中的每个成员,最后扩展为结果的列表。
  • ${parameter/pattern/string}${parameter//pattern/string}

    pattern 被扩展为一个模式,就像路径扩展中一样。parameter 被扩展,其值中最长的匹配 pattern 的内容被替换为 string。在第一种形式中,只有第一个匹配被替换。第二种形式使得 pattern 中所有匹配都被替换为 string。

    • 如果 pattern 以 # 开始,它必须匹配 parameter 扩展后值的首部。
    • 如果 pattern 以 % 开始,它必须匹配 parameter 扩展后值的尾部。
    • 如果 string 是空值,pattern 的匹配都将被删除, pattern 之后的 / 将被忽略。
    • 如果 parameter 是 @ 或者是 *, 则替换操作将依次施用于每个位置参数,最后扩展为结果的列表。
    • 如果 parameter 是一个数组变量,下标是 @ 或者是 *, 模式删除将依次施用于数组中的每个成员,最后扩展为结果的列表。

前段时间遇到个奇怪的问题,在 qtcreator 中 qDebug 语句的打印内容一直出不来,解决方法是在构建工具链设置中新增一个环境变量:QT_ASSUME_STDERR_HAS_CONSOLE=1

具体步骤(英文菜单):
点击 qtcreator 工具栏,依次点击 Tools > Options > Kits,之后选择正在使用的 Kits,滚动找到 Environment, 点击 Change 然后新增上面提到的环境变量即可。

参考链接:https://stackoverflow.com/questions/41425530/qtcreator-qdebug-messages-not-shown

有时候由于网络问题,会发现 android-studio 或 idea 下载不懂 gradle,可以修改 gradle-wrapper.properties 配置文件中的 distributionUrl 选项来解决这个问题。

1
distributionUrl=https\://mirrors.cloud.tencent.com/gradle/gradle-5.1.1-all.zip

这个选项表示从腾讯提供的 gradle 镜像服务下载数据,注意替换上面示例链接末尾的具体文件名。

可以访问此链接查看有哪些版本的 gradle 可以下载:https://mirrors.cloud.tencent.com/gradle/

在公司内部服务器上搭了一个 Nextcloud 服务,跑起来之后发现没有日历、邮件等应用,且不能打开应用商店,分析了服务日志发现是由于网络问题。

启动服务时加上代理即可正常,比如使用 docker 跑的话:

1
docker run --name nextcloud -p 8080:80 -e http_proxy=http://192.168.1.100:1081 -e https_proxy=http://192.168.1.100:1081 nextcloud

代理相关参数解释:

  • -e http_proxy 为容器内 NC 服务设置 http 代理地址和端口
  • -e https_proxy 同上

以前一直在用 firefox 火狐浏览器作为主力浏览器,主要是因为它可以做到不翻墙就实现全平台(linux/mac/windows/android/ios)数据同步,只是 firefox 在 linux 下长时间运行后会变得打开新网页速度很慢,必须要退出程序重新打开才能恢复正常访问速度,给我这种感觉已经很长一段时间了,搜索不到解决方法,自己也没有摸索出来根本原因,但苦于没有更好的选择,只能一直将就下去。

不久前巨硬为 linux 版 edge 浏览器增加了账户同步功能,我终于等来了一个新的,不翻墙全平台数据同步浏览器,虽然是测试版,但巨硬维护很积极,bug 修复更新很及时,相信很快就会发布正式版。

对我来说 edge 浏览器在各个平台上的使用体验都很符合需求,唯独有一点让我很不舒服,就是 ctrl-tab 切换标签页的方式,firefox 浏览器按一下 ctrl-tab 默认会在最近使用的两个标签页中切换,而 edge 则是循环得朝着右边的标签页切换,chrome 也是同样的行为。在搜索这个问题相关的内容时发现,有一部分人觉得这种方式很好,当然也有一部分人和我有同样的感觉,所以这个问题比较主观,并不是说 edge 或 chrome 的切换模式就一定是不好用的。当然 edge 或 chrome 能够像 firefox 一样对这个行为在设置里提供一个修改选项自然是最好的结果。

经过一段时间的摸索,最终找到了一个满足需求的扩展程序,在 edge 和 chrome 的官方扩展仓库中都能找到,链接分别是:

https://microsoftedge.microsoft.com/addons/detail/quickey-%E2%80%93-the-quick-tab-s/mcjciddpjefdpndgllejgcekmajmehnd

https://chrome.google.com/webstore/detail/quickey-%E2%80%93-the-quick-tab-s/ldlghkoiihaelfnggonhjnfiabmaficg

扩展程序代码仓库是: https://github.com/fwextensions/QuicKey

QuickKey 扩展程序提供了很多丰富的功能,感兴趣的可以自行探索。

针对修改 ctrl-tab 行为的功能并不是默认启用的,需要手动修改一些浏览器配置,官方有详细的文档:https://fwextensions.github.io/QuicKey/ctrl-tab/

下面我筛选出适合我的步骤,并翻译如下,此方法适用于 edge 和 chrome。

阅读全文 »

我用来创建热点的工具是 create_ap 可以直接去官方仓库中查看 README 来安装:https://github.com/oblique/create_ap

把 USB 无线网卡插到运行 linux 系统的机器上,然后使用 lsusb 命令查看信息,可以得到如下:

1
Bus 001 Device 006: ID 0bda:8179 Realtek Semiconductor Corp. RTL8188EUS 802.11n Wireless Network Adapter

可以看到芯片是 RTL8188EUS,在 manjaro 系统下,虽然可以识别设备,也能正常连接无线网使用,但默认驱动不能用来创建 wifi 热点,所以需要手动安装一个新的驱动。

经过搜索和不断测试,最终确定一个可用驱动:
https://github.com/aircrack-ng/rtl8188eus

手动安装方法可以参考驱动代码仓库的 README 文档。

如果是 arch 系的系统,比如 manjaro 系统,可以直接 aur 仓库里的包:8188eu-aircrack-dkms-git,这个包里带有必要的配置文件,安装完成后重启即可生效。

驱动生效后就可以使用 create_ap 工具创建 wifi 热点了。

ubuntu 系统 16.04 版本中,最新版本的 python 是 3.5,从系统源中找不到更新版本的 python,本文介绍一种安装 python3.8 的方法,以及安装对应版本的 pip。

安装 python3.8

执行如下命令增加 ppa 仓库,并更新源数据:

1
2
sudo add-apt-repository ppa:deadsnakes/ppa
sudo apt update

如果提示找不到 add-apt-repository 命令,执行如下命令安装:

1
sudo apt install software-properties-common

更新完成源数据之后,就可以安装 ppa 仓库中的包了,这个仓库中不止是包含 python3.8,还包含其他版本的 python 包,详细情况可查看链接:

https://launchpad.net/~deadsnakes/+archive/ubuntu/ppa

执行以下命令安装 python3.8 相关的包:

1
sudo apt install python3.8 python3.8-dev python3.8-distutils python3.8-venv
阅读全文 »