替代notepad++,notepad--介绍及插件cmake编译

简介: 替代notepad++,notepad--介绍及插件cmake编译

Notepad++ 是一个文本编辑器小软件,用来替代windows自带的记事本。然而Notepad++软件的作者太霸道,如果你不赞同他的观点,Notepad++将会在你的源码里面插入随机字符。推荐一款国产的开源跨平台软件NDD(notepad--),功能一点儿不弱,体积小巧打开速度快,且带有文件夹比对功能,连收费的beyondCompare都省了。且可以为它贡献插件啦,添加一些有意思的功能,比如我想给它添加个ChatGPT聊天机器人插件。期待更多优秀的国产软件,为国产化崛起贡献力量。



NDD(notepad--)介绍


Notepad–是一个使用C++编写的文本编辑器,目前支持Win/Linux/Mac平台。在gitee上的项目名称为NDD。gitee仓库地址:


https://gitee.com/cxasm/notepad--


目标是要进行文本编辑类软件的国产可替代,重点在国产Uos/Linux系统、Mac 系统上发展。


一个支持windows/linux/mac的文本编辑器,目标是要国产替换同类软件,来自中国。对比其它竞品Notepad类软件而言,优势是可以跨平台,支持linux mac操作系统。


可直接下载使用,发布版的软件下载地址:


https://gitee.com/cxasm/notepad--/releases/tag/v1.21


msvc工具链下载安装


Microsoft C++ Build Tools,通过可编写脚本的独立安装程序提供 MSVC 工具集,无需使用 Visual Studio。 如果从命令行界面(例如,持续集成工作流中)生成面向 Windows 的 C++ 库和应用程序, 推荐使用此工具。


为什么使用msvc工具?因为Visual Studio太大啦,好几个G,且我已安装过一个版本了,不想再安装一个新版本了。编译NDD源码的需注意,QT框架需要5.11以上。c++编译器至少需要支持c++17以上才行。直接下载msvc工具链1G左右大小,且下载速度超快。


msvc工具链下载地址:


Microsoft C++ Build Tools - Visual Studio


安装这个需要注意的是,一定要勾选用于Windows的c++ Cmake工具这一项。



NDD源码编译


虽然NDD发布版提供了现成的软件可以用,但是对于开发来说,开发的插件必须使用同一套的MSVC和QT版本才行(VS2019和QT5.15.2),否则容易出现兼容性问题,对于开发测试插件来说,直接连ndd源码也一块儿编译,最简单直接。且最终想要贡献插件时也不用担心,作者鼓励大家定做插件,热门插件会给你合并进发布版中。


源码编译比较简单,作者提供的有编译文档介绍,windows下推荐编译环境:vs2017及以上,qt tool 插件。这里介绍下使用cmake编译,也很简单,在源码的how_build目录里有CMakeLists.txt文件,拷贝到项目根目录中,设置好cmake环境,就可以直接编译了。


cmake_minimum_required(VERSION 3.16)
project(NotePad-- VERSION 1.22.0)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
add_definitions(
        -DCMAKE_CXX_STANDARD=17
)
set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent Network PrintSupport XmlPatterns)
# qscint 关键依赖库
add_subdirectory(${PROJECT_SOURCE_DIR}/src/qscint)
# 插件库包含
# helloworld 动态插件库
add_subdirectory(${PROJECT_SOURCE_DIR}/src/plugin/helloworld)
# win下需要开启UNICODE进行支持TCHAR
if(CMAKE_HOST_WIN32)
    add_definitions(-D_UNICODE -DUNICODE)
endif()
if(${PLUGIN_EN})
    if(${PLUGIN_EN}  STREQUAL on)
        add_definitions(-DNO_PLUGIN=1)
    endif(${PLUGIN_EN})    
endif()
file(GLOB UI_SRC ${PROJECT_SOURCE_DIR}/src/*.ui)
set(UI_SRC ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/cceditor/ccnotepad.ui)
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/src/cceditor SRC)
if(CMAKE_HOST_WIN32)
# 添加 WIN32 保证主程序启动没有命令行
    list(APPEND WIN_RCS ${PROJECT_SOURCE_DIR}/src/RealCompareToMinGw.rc)
    add_executable(${PROJECT_NAME} WIN32 ${WIN_RCS} ${SRC} ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/RealCompare.qrc)
else()
    add_executable(${PROJECT_NAME} ${SRC} ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/RealCompare.qrc)
endif()
target_include_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/cceditor
${PROJECT_SOURCE_DIR}/src/qscint/src
${PROJECT_SOURCE_DIR}/src/qscint/src/Qsci
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/src
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/include
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/lexlib
${PROJECT_SOURCE_DIR}/src/qscint/scintilla/boostregex
)
target_link_libraries(${PROJECT_NAME} qscint Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network  Qt5::PrintSupport Qt5::XmlPatterns)
# set(PROJECT_BINARY_DIR "${PROJECT_BINARY_DIR}/bin")
# set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
if(CMAKE_HOST_UNIX)
    install(
        TARGETS ${PROJECT_NAME}
        DESTINATION "bin"
    )
    install(DIRECTORY  ${PROJECT_SOURCE_DIR}/src/linux/usr
            DESTINATION "/")
    include(${PROJECT_SOURCE_DIR}/cmake/deb_package_config.cmake) 
    include(CPack)
elseif(CMAKE_HOST_WIN32)
    install(TARGETS ${PROJECT_NAME}
            DESTINATION "/")
    install(DIRECTORY  ${PROJECT_SOURCE_DIR}/build/bin/
            DESTINATION "/")
    # 设置软件版本
    set(CPACK_PACKAGE_NAME "NotePad--")
    set(CPACK_PACKAGE_DESCRIPTION "NotePad--")
    set(CPACK_PACKAGE_COPYRIGHT "Copyright (c) 2023")
    set(CPACK_PACKAGE_VERSION "1.22.0")
    set(CPACK_PACKAGE_VERSION_MAJOR "1")
    set(CPACK_PACKAGE_VERSION_MINOR "22")
    set(CPACK_PACKAGE_VERSION_PATCH "0")
    #include(${PROJECT_SOURCE_DIR}/cmake/nsis_package_config.cmake)
    include(CPack)
endif()


源码编译注意事项:


# qscint 关键依赖库
add_subdirectory(${PROJECT_SOURCE_DIR}/src/qscint)
......
target_link_libraries(${PROJECT_NAME} qscint Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network  Qt5::PrintSupport Qt5::XmlPatterns)


从以上可看出,源码里附带的那个how_build文件夹,拷贝出的默认的CmakeLists.txt文件,是包含了 qscint 关键依赖库,且默认里面是把qscint生成的静态的。感觉这样有点别扭。因为最终是想把qscint库动态使用的。


因此这里编译NDD源码,注释掉了这个,先单独编译qscint为动态库。有个注意事项,编译qscint动态库,需增加宏定义add_definitions(-DQSCINTILLA_MAKE_DLL),既让Q_DECL_EXPORT生效。这个会让动态库同时生成dll和lib文件。


然后修改NDD主程序的CmakeLists.txt文件,引入和使用上一步生成的qscint库。


本以为很顺利,结果编译报错啦。



解决办法:


再编译NDD源码时,改下库的使用方式。在 windows 中构建此库时应该采用 O DECL EXPORT, 并且在 windows 中使用此库时应该采用 Q DECL IMPORT。



NDD插件demo及编译


插件的制作和编译,作者提供的有插件编程开发说明文档。这里介绍下cmake的编译方法,相对更简单些。插件需要依赖qscintila库,先编译出qscintila库。源码notepad--\src\qscint文件夹,CmakeLists.txt文件几乎不用咋改动,即可成功编译。需要注意的是:


set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
add_definitions(-DBOOST_REGEX_STANDALONE)


增加-DBOOST_REGEX_STANDALONE这个宏定义,否则还需要依赖Boost库。加上这个可独立编译成功啦。 需要注意的是,cmakeLists.txt 中增加以下配置,支持debug和其他模式下找到对应的库。


link_directories(
        ${CMAKE_CURRENT_SOURCE_DIR}/
)
target_link_libraries(${PROJECT_NAME} PRIVATE
        debug qmyedit_qt5d
        optimized qmyedit_qt5)


另外还需注意的是,如果是要把 qscintila库动态的使用,则需要定义宏:


add_definitions(-DQSCINTILLA_MAKE_DLL)


这个是#define QSCINTILLA_EXPORT Q_DECL_EXPORT,Q_DECL_EXPORT宏主要为了导出这个类,生成.dll的同时生成.lib文件(注意这里的lib文件不是静态库,而是供外部链接使用的)提供给外部接口供其他类使用。


cmake_minimum_required(VERSION 3.16)
project(qscint CXX)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
add_definitions(-DBOOST_REGEX_STANDALONE)
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent Network PrintSupport)
aux_source_directory(${PROJECT_SOURCE_DIR}/src SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/lexers SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/lexlib SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/src SRC)
aux_source_directory(${PROJECT_SOURCE_DIR}/scintilla/boostregex SRC)
file(GLOB MOC_HEADER ${PROJECT_SOURCE_DIR}/src/Qsci/*.h)
#message(${MOC_HEADER})
add_library(${PROJECT_NAME} STATIC ${SRC} ${MOC_HEADER})
# add_definitions(-DQSCINTILLA_MAKE_DLL)
# add_library(${PROJECT_NAME} SHARED ${SRC} ${MOC_HEADER})
target_compile_definitions(${PROJECT_NAME} PRIVATE SCINTILLA_QT SCI_LEXER INCLUDE_DEPRECATED_FEATURES)
target_include_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}/scintilla/lexlib
${PROJECT_SOURCE_DIR}/scintilla/boostregex
)
target_include_directories(${PROJECT_NAME} PUBLIC
${PROJECT_SOURCE_DIR}/src
${PROJECT_SOURCE_DIR}/src/Qsci
${PROJECT_SOURCE_DIR}/scintilla/src
${PROJECT_SOURCE_DIR}/scintilla/include)
target_link_libraries(${PROJECT_NAME} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network Qt5::PrintSupport)
if("${CMAKE_BUILD_TYPE}" STREQUAL "Release")
    set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "qmyedit_qt5")
else()
    set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME "qmyedit_qt5d")
endif()


插件demo


#include <qobject.h>
#include <qstring.h>
#include <pluginGl.h>
#include <functional>
#include <qsciscintilla.h>
#include "qttestclass.h"
#include "NDDMyPlugin.h"
#define NDD_EXPORTDLL
#if defined(Q_OS_WIN)
  #if defined(NDD_EXPORTDLL)
    #define NDD_EXPORT __declspec(dllexport)
  #else
    #define NDD_EXPORT __declspec(dllimport)
  #endif
#else
  #define NDD_EXPORT __attribute__((visibility("default")))
#endif
#ifdef __cplusplus
  extern "C" {
#endif
  NDD_EXPORT bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData);
  NDD_EXPORT int NDD_PROC_MAIN(QWidget* pNotepad, const QString& strFileName, std::function<QsciScintilla* ()>getCurEdit, NDD_PROC_DATA* procData);
#ifdef __cplusplus
  }
#endif
NDDMyPlugin *nddMyPlugin = nullptr;
static NDD_PROC_DATA s_procData;
static QWidget* s_pMainNotepad = nullptr;
std::function<QsciScintilla* ()> s_getCurEdit;
bool NDD_PROC_IDENTIFY(NDD_PROC_DATA* pProcData)
{
  if(pProcData == NULL)
  {
    return false;
  }
  pProcData->m_strPlugName = QObject::tr("Hello World Plug");
  pProcData->m_strComment = QObject::tr("char to Upper.");
  pProcData->m_version = QString("v1.0");
  pProcData->m_auther = QString("yangqq.xyz");
  pProcData->m_menuType = 1;
  return true;
}
//则点击菜单栏按钮时,会自动调用到该插件的入口点函数。
//pNotepad:就是CCNotepad的主界面指针
//strFileName:当前插件DLL的全路径,如果不关心,则可以不使用
//getCurEdit:从NDD主程序传递过来的仿函数,通过该函数获取当前编辑框操作对象QsciScintilla
//pProcData:如果pProcData->m_menuType = 0 ,则该指针为空;如果pProcData->m_menuType = 1,则该指针有值。目前需要关心s_procData.m_rootMenu
//开发者可以在该菜单下面,自行创建二级菜单
int NDD_PROC_MAIN(QWidget* pNotepad, const QString &strFileName, std::function<QsciScintilla*()>getCurEdit, NDD_PROC_DATA* pProcData)
{
  QsciScintilla* pEdit = getCurEdit();
  if (pEdit == nullptr)
  {
    return -1;
  }
  //务必拷贝一份pProcData,在外面会释放。
  if (pProcData != nullptr)
  {
    s_procData = *pProcData;
  }
  s_pMainNotepad = pNotepad;
  s_getCurEdit = getCurEdit;
  //如果pProcData->m_menuType = 1;是自己要创建二级菜单的场景。则通过s_procData.m_rootMenu 获取该插件的菜单根节点。
  //插件开发者自行在s_procData.m_rootMenu下添加新的二级菜单项目
    //QMenu* menu = s_procData.m_rootMenu;
    if (!nddMyPlugin)
    {
        nddMyPlugin = new NDDMyPlugin(s_pMainNotepad, strFileName, nullptr, s_pMainNotepad);
        nddMyPlugin->getViewMenu(s_procData.m_rootMenu);
        nddMyPlugin->setScintilla(s_getCurEdit);
    }
  return 0;
}


附cmake


cmake_minimum_required(VERSION 3.16)
project(helloworld)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_PREFIX_PATH "D:/Qt5.12.11/Qt5.12.11/5.12.11/msvc2015_64/lib/cmake")
find_package(Qt5 REQUIRED COMPONENTS Core Gui Widgets Concurrent Network PrintSupport XmlPatterns)
add_definitions(-D_UNICODE -DUNICODE)
file(GLOB UI_SRC ${PROJECT_SOURCE_DIR}/*.ui)
file(GLOB SRC ${PROJECT_SOURCE_DIR}/*.cpp)
file(GLOB MOC_HEADER ${PROJECT_SOURCE_DIR}/*.h)
# add_executable(${PROJECT_NAME} ${IS_WIN} ${SRC} ${UI_SRC} ${PROJECT_SOURCE_DIR}/src/RealCompare.qrc)
#link_directories(
#        ${CMAKE_CURRENT_SOURCE_DIR}/
#)
find_library(QSCINT_LIB qmyedit_qt5 PATH ${CMAKE_CURRENT_SOURCE_DIR}/)
add_library(${PROJECT_NAME} SHARED ${SRC} ${UI_SRC} ${MOC_HEADER})
target_include_directories(${PROJECT_NAME} PRIVATE
${PROJECT_SOURCE_DIR}
${PROJECT_SOURCE_DIR}/../../include
${PROJECT_SOURCE_DIR}/../../qscint/src
${PROJECT_SOURCE_DIR}/../../qscint/src/Qsci
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/src
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/include
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/lexlib
${PROJECT_SOURCE_DIR}/../../qscint/scintilla/boostregex
)
#set(QS_CINT_LIB ${CMAKE_CURRENT_SOURCE_DIR}/qmyedit_qt5.lib)
#target_link_libraries(${PROJECT_NAME} PRIVATE
#        debug qmyedit_qt5_d
#        optimized qmyedit_qt5)
target_link_libraries(${PROJECT_NAME} PRIVATE ${QSCINT_LIB} Qt5::Core Qt5::Gui Qt5::Widgets Qt5::Concurrent Qt5::Network  Qt5::PrintSupport Qt5::XmlPatterns)


其他资源


cmake核心知识点整理_cmake file(glob_今耕明收的博客-CSDN博客


Cmake 链接外部库_cmake 链接动态库_泡沫o0的博客-CSDN博客


QT知识点总结(三)_q_decl_import_Chiang木的博客-CSDN博客


【Qt】 error: LNK1107: 文件无效或损坏: 无法在 0x310 处读取_qt lnk1107_郭老二的博客-CSDN博客

相关文章
|
9月前
|
测试技术
notepad++安装HexEditor插件查看二进制文件
有时候我们需要分析二进制文件,但是分析二进制文件直接用编辑器查看会出现乱码的情况,本文在 notepad++ 软件上安装一个 HexEditor 插件,可方便分析二进制文件。
328 0
|
10月前
|
人工智能 JSON 机器人
NDD(notepad--)的AI机器人插件制作过程
NDD(notepad--)的AI机器人插件制作过程
|
10月前
|
JSON 数据格式
notepad++安装json插件
notepad++安装json插件
175 0
|
JavaScript 前端开发
JavaScript 技术篇 - 实现一键压缩、格式化js代码实例演示,将js代码压缩为min.js方法,Notepad++工具JSTool插件安装
JavaScript 技术篇 - 实现一键压缩、格式化js代码实例演示,将js代码压缩为min.js方法,Notepad++工具JSTool插件安装
756 0
JavaScript 技术篇 - 实现一键压缩、格式化js代码实例演示,将js代码压缩为min.js方法,Notepad++工具JSTool插件安装
notepad++查看二进制.class文件——HexEditor插件(64/32位)安装教程
最近在学习JVM的时候,碰到需要查看.class文件,这里给大家推荐两种方式:
notepad++查看二进制.class文件——HexEditor插件(64/32位)安装教程
notepad++ 插件推荐——快速定位文件
介绍Notepad++的文章很多,我这里就不赘述了。简言之,是一个轻便的文本编辑工具。结合丰富的插件,可以实现很多功能,可以成为一个轻量级的IDE,用来做脚本开发非常合适。 这里介绍几个插件可以用来进行文件定位。
1633 0
|
XML JavaScript 前端开发
Notepad++中常用的插件【转】
转自:http://www.crifan.com/files/doc/docbook/rec_soft_npp/release/htmls/npp_common_plugins.html 1.4. Notepad++中常用的插件   1.4.1. 插件管理器: Plugin Manager 插件功能:此插件可以帮你管理插件,包括查看当前已经安装的插件有哪些,以及自动帮你下载相应的插件。
2401 0
|
JSON JavaScript 前端开发
Notepad++ 插件整理
Emmet Emmet的前身是Zen Coding,一款使用仿CSS选择器的语法来快速开发HTML和CSS的插件,是前端开发神器。它无视了编辑器的自动提示和自动完成,秒杀了你自定义的各种快捷键或者 AHK 的热字符串,以智能简洁高效的缩短输入,带给你超快速地书写各种复杂而枯燥的 HTML 和 CSS 代码的体验。
1442 0