关于CKEditor4.5.6的使用,自定义toolbar配置,上传图片案例(SpringMVC+MyBatis案例),自定义行高,去编辑器的中内容,将编辑器中内容设置到指定的位置等

简介: 关于CKEditor的一个配置整理,改文件为config.js:文件内容如下: /** * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved. * For licensing, see LICENSE.md or http://ckeditor.com/


关于CKEditor的一个配置整理,改文件为config.js

文件内容如下:

/**
 * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
 * For licensing, see LICENSE.md or http://ckeditor.com/license
 */

CKEDITOR.editorConfig = function( config ) {
 // Define changes to default configuration here. For example:
 // config.language = 'fr';
 // config.uiColor = '#AADC6E';
 config.toolbarGroups = [
  { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },
  { name: 'clipboard', groups: [ 'clipboard', 'undo' ] },
  { name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },
  { name: 'forms', groups: [ 'forms' ] },
  { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },
  '/',
  { name: 'links', groups: [ 'links' ] },
  { name: 'insert', groups: [ 'insert' ] },
  { name: 'colors', groups: [ 'colors' ] },
  { name: 'styles', groups: [ 'styles' ] },
  { name: 'tools', groups: [ 'tools' ] },
  { name: 'paragraph', groups: [ 'list', 'blocks', 'bidi', 'align', 'indent', 'paragraph' ] },
  { name: 'others', groups: [ 'others' ] },
  { name: 'about', groups: [ 'about' ] }
 ];
 // config.removeButtons = 'Source,Save,Templates,Cut,Undo,Find,Scayt,SelectAll,Paste,Copy,Redo,NewPage,Preview,Print,Form,Bold,RemoveFormat,Link,Image,TextColor,Outdent,JustifyLeft,BidiLtr,Blockquote,NumberedList,UIColor,lineheight';
 config.line_height ='8px;9px;10px;11px;12px;13px;14px;15px;16px;17px;18px;19px;20px;21px;22px;23px;24px;25px;26px;27px;28px;29px;30px;31px;32px;33px;34px;35px;36px;37px;38px;39px;40px;41px;42px;43px;44px;45px;46px;47px;48px;49px;50px;51px;52px;53px;54px;55px;56px;57px;58px;59px;60px;61px;62px;63px;64px;65px;66px;67px;68px;69px;70px;71px;72px;';
 config.skin = 'office2013';
 config.extraPlugins='imagepaste';
 config.pasteFromWordRemoveFontStyles = false;
 config.pasteFromWordRemoveStyles = false;
 config.extraPlugins = 'uploadwidget';
 config.extraPlugins = 'notificationaggregator';
 config.extraPlugins = 'notification';
 config.extraPlugins = 'uploadimage';
 config.extraPlugins = 'toolbar';
 config.extraPlugins = 'button';
 config.extraPlugins = 'filetools';
 config.extraPlugins = 'clipboard';
 config.extraPlugins = 'dialog';
 config.extraPlugins = 'dialogui';
 config.extraPlugins = 'widget';
 config.extraPlugins = 'lineutils';
 config.extraPlugins = 'widget';
 config.SecureImageUploads = true;
 config.image_previewText=' '; //预览区域显示内容
 //config.filebrowserUploadUrl: "import/ckeditorUploadFile.action";
 config.filebrowserImageUploadUrl = basePath + "/import/ckeditorUploadFile.action?type=Image"; //待会要上传的action或servlet
 
};

 

关于图片上传部分可以参考:

http://blog.csdn.net/itmyhome1990/article/details/17264627

 

实现过程中的一个案例

/*

 * name       :tuzuoquan

 * mail       :tuzq@XXXX.cn

 * date       :2016/01/13

 * version    :1.0

 * description:XXXXXX对应的js

 * CopyRight (C) 2015-12-31

 */

if (CKEDITOR.env.ie && CKEDITOR.env.version < 9)

   CKEDITOR.tools.enableHtml5Elements(document);

 

/**

 * 编辑器对应的操作方法

 *

 * 关于在线编辑器的文档:http://sdk.ckeditor.com/samples/resize.html

 */

var CKEDITORHandler = (function($) {

   return {

      /**

       * 初始化参数配置

       */

      ckeditorConfig:function(){

          //去掉开始进来的时候自动添加 BR

          CKEDITOR.config.enterMode = CKEDITOR.ENTER_BR;

          //去掉开始进来的时候自动添加P

          CKEDITOR.config.shiftEnterMode = CKEDITOR.ENTER_P;

          CKEDITOR.config.font_names='微软雅黑;宋体;新宋体;黑体;隶书;幼圆;楷体_GB2312;仿宋_GB2312;方正舒体;方正姚体;华文隶书;华文新魏;华文行楷;sans-serif;Arial;Comic Sans MS;Courier New;Tahoma;Times New Roman;Verdana;'

          CKEDITOR.config.line_height="1em;1.1em;1.2em;1.3em;1.4em;1.5em";

       },

      /**

       * 初始化工具条的相关信息

       */

      initToolBar:function(){

         CKEDITOR.config.toolbar = 'Full';

  

         /**

          * 其中("-")为空间栏的水平分割,("/")为换行

          *

          * 以下:Full表示的所有的操作

          */

         CKEDITOR.config.toolbar_Full =

         [

            { name: 'document', groups: [ 'mode', 'document', 'doctools' ] },

            { name: 'clipboard', groups: [ 'clipboard', 'undo' ] },

            { name: 'editing', groups: [ 'find', 'selection', 'spellchecker', 'editing' ] },

            { name: 'forms', groups: [ 'forms' ] },

            { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },

            '/',

            { name: 'links', groups: [ 'links' ] },

            { name: 'insert', groups: [ 'insert' ] },

            { name: 'colors', groups: [ 'colors' ] },

            { name: 'styles', groups: [ 'styles' ] },

            { name: 'tools', groups: [ 'tools' ] },

            { name: 'paragraph', groups: [ 'list', 'blocks', 'bidi', 'align', 'indent', 'paragraph' ] },

            { name: 'others', groups: [ 'others' ] },

            { name: 'about', groups: [ 'about' ] }

         ];

  

         CKEDITOR.config.toolbar_Basic =

         [

             ['Source','Preview'],

             ['Cut','Copy','Paste','PasteText','PasteFromWord','-','SpellChecker'],

             ['Undo','Redo','-','Find','Replace','-','SelectAll','RemoveFormat'],

             ['Form', 'Checkbox', 'Radio', 'TextField', 'Textarea', 'Select', 'Button', 'ImageButton', 'HiddenField'],

             ['Bold','Italic','Underline','Strike','-','Subscript','Superscript'],

             ['NumberedList','BulletedList','-','Outdent','Indent'],

             ['JustifyLeft','JustifyCenter','JustifyRight','JustifyBlock'],

             ['Link','Unlink','Anchor'],

             ['Image','Flash','Table','SpecialChar'],

             ['Styles','Format','Font','FontSize'],

             ['TextColor','BGColor'],

             ['lineheight']

         ];

       },

      /**

       * 在线编辑器的初始化过程

       * textContent   :表示的是文本组件的内容

       */

      init:function(textContent){

          //注意:这里的tpl-content-editor是编辑器对应的id

          if(CKEDITOR.instances.tplContentEditor) {

             var editor = CKEDITOR.instances["tplContentEditor"];

  

             //console.log("1------------------------------------------");

             //console.log(editor.getData());

             //editor.setData(editor.setData(textContent));

             //console.log("2------------------------------------------");

            

             //销毁编辑器,然后新增一个

             if(editor) editor.destroy(true);

          }

         

          CKEDITORHandler.ckeditorConfig();

          //初始化工具栏

          CKEDITORHandler.initToolBar();

         

          CKEDITOR.replace("tplContentEditor",

          {

             toolbar:'Basic',

             height:'300',

             width:'auto'

          });

         

          //为编辑器设置内容

          CKEDITOR.instances.tplContentEditor.setData(textContent);

       },

       /**

       * 2、判断一个字符串变量是否为空

       * 如果不为空:返回true

       * 如果为空:返回false

       */

      isNotBlank:function(variable){

         return (variable != null && typeof(variable) != "undefined" && variable != undefined && variable != "") ? true : false;

      },

       /**

        * 通过编辑的icon获得组件元素,查找父元素,直到找到含有className这个类选择器的元素停止

        * domEle         :表示的是编辑的元素

        */

       /**

         * str1这个原始的字符串中的str2全部换成str3

         * str1      :最原始的字符串

         * str2      :要被替换的字符串

         * str3      :最终替换成的字符串

         *

         * 此外可以增加String对象的原型方法:

         * String.prototype.replaceAll = function(str2,str3){

       *     return this.replace(new RegExp(str2,"gm"),str3);

       * }

         */

        replaceAll:function(str1,str2,str3) {

            var newStr  = str1;

            if(this.isNotBlank(str1)) {

                //其中gm中的g表示"执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)"

                //其中gm中的m表示执行多行匹配

                newStr = str1.replace(new RegExp(str2,"gm"),str3);

            }

            return newStr;

        },

        /**

         * 清除样式

         */

        removeCss:function(id,childPathOfSelectedElement,cssType){

            //替换原来的css样式

            var oldStyleCss = $("#generatedCss").html().replace(

                new RegExp("#"+ id + childPathOfSelectedElement + ".*?{.*"+cssType+".*?}"),"");

 

            oldStyleCss = this.replaceAll(oldStyleCss,"\r\n","");

 

            $("#generatedCss").text(oldStyleCss);

        },

       obtainComponentEle:function(domEle,className) {

          var tempObj = domEle;

          while(!$(tempObj).parent().hasClass(className)) {

             tempObj = $(tempObj).parent().get(0);

          }

         

          return $(tempObj).parent().get(0);

       },

       /**

        * 存储的是要编辑的对象

        */

       editObj : null,

       /**

        * 表示的是否是多列的

        */

       isMultiseriate : false,

       /**

        * 1、点击编辑按钮的时候执行的操作

        * domEle                     :代表的是编辑按钮

        * selectedElementInfo        :表示的是被选中的元素

        * childPathOfSelectedElement :表示的是放置内容的位置

        *

        * isMultiseriate             :表示的是是否多列

        * obj                        :表示的是被点击的个元素

        *

        * 如果是单列的:

        * 比如点击"text"组件"编辑"按钮的时候传递进入的参数是:(this,selectedElementInfo,'',false,'')

        * 如果实在配置文件中点击弹出的,传递的参数是:('',selectedElementInfo,' .xxx .xxx',false,''),其中' .xxx .xxx'是你要改变的元素

        *

        * 如果是多列的:

        * ('',selectedElementInfo,'',true,editObj)

        */

       tplEditSelectedContent:function(domEle,selectedElementInfo,childPathOfSelectedElement,isMultiseriate,editObj) {

          //存储的是点击的对象

          CKEDITORHandler.editObj = editObj;

          //存储是否是多列的情况

          CKEDITORHandler.isMultiseriate = isMultiseriate;

         

          //如果是多列的

          if(CKEDITORHandler.isMultiseriate) {

             //获得要编辑的元素的内容:

             var textContent = $(CKEDITORHandler.editObj).html();

          } else {

             //获得domEle这个编辑按钮的组件

             var componentEle = null;

             if(CKEDITORHandler.isNotBlank(domEle)) {

                componentEle = CKEDITORHandler.obtainComponentEle(domEle,"tpl-monitored-class");

             } else {

                var id = selectedElementInfo.get("id");

                componentEle = $("#" + id);

             }

            

             //将当前元素的id存储到隐藏域中

             $(".tpl-edit-popup-window #componentId").val($(componentEle).attr("id"));

             //存储要设置的元素的值

             if(!CKEDITORHandler.isNotBlank($.trim(childPathOfSelectedElement))) {

                childPathOfSelectedElement = " .tpl-component-2015-12-30-text-content";

             }

             //将要编辑的后代的值存到隐藏域中

             $(".tpl-edit-popup-window #childPathOfSelectedElement").val(childPathOfSelectedElement);

            

             //获得当前要编辑的元素的id

             var componentId = $(componentEle).attr("id");

             //获得要编辑的元素的内容:

             var textContent = $("#" + componentId + " " + childPathOfSelectedElement).html();

          }

         

          //获得文本组件中的内容

           CKEDITORHandler.init(textContent);

 

            $('.theme-popover-mask').fadeIn(10);

           $('.theme-popover').slideDown(20);

       },

       /**

        * 点击取消的时候执行的动作

        * @return

        */

       tplEditCancel:function() {

          $('.theme-popover-mask').fadeOut(100);

          $('.theme-popover').slideUp(200);

       },

       /**

        * 点击"确定的时候执行的动作"

        * @return

        */

       tplEditOk:function() {

          //获得编辑器中的内容

          var editorContent = CKEDITOR.instances.tplContentEditor.getData();

          var id = selectedElementInfo.get("id");

          /**

           * 判断是否是多列的

           */

          if(CKEDITORHandler.isMultiseriate) {

             $(CKEDITORHandler.editObj).empty();

             $(CKEDITORHandler.editObj).append(editorContent);

          } else {

             //1、首先判断编辑器内容中第一个子标签的内容是否是<pre>,若是,则在后面不在添加<pre>

             //$("<div></div>").append(editorContent).first().prop("tagName");

             //$("<div></div>").append(editorContent).first().prop("nodeName");

            

             //获得要修改的组件的id

             var componentId = $(".tpl-edit-popup-window #componentId").val();

             //获得组件中要放置内容的元素

             var childPathOfSelectedElement = $(".tpl-edit-popup-window #childPathOfSelectedElement").val();

            

             $("#" + componentId + " " + childPathOfSelectedElement).empty();

             $("#" + componentId + " " + childPathOfSelectedElement).append(editorContent);  

          }

          if($("#" + id + " .picturegroup #topMarquee_1 li").length>0){

             var currCount = $("#" + id + " .picturegroup #topMarquee_1 li").length;

               var baseHeight = 0;

            var i=0;

            for(;i<currCount;i++){

                baseHeight += $("#" + id + " .picturegroup #topMarquee_1 li").eq(i).outerHeight(true);

            }

               var dyHeight = baseHeight  + 'px';

               var divHeight = baseHeight  * 2  + 'px';      

               $("#" + id + " .picturegroup .picture-holder").css("height", dyHeight);

               $("#" + id + " .picturegroup  div").css("height", divHeight);

         

     

          }

          /*if($("#" + id + " .picturegroup #erwm").length>0){

             this.removeCss(id," .picturegroup","height");

             this.removeCss(id," .picturegroup #erwm","height");

             var height = parseFloat($("#picHeight").val());

             var spanHeight = $("#" + id + " .picturegroup #erwm .bottomContent").height();

             console.log(spanHeight);

             $("#" + id + " .picturegroup").css("height","'+(height+spanHeight)+'+'px'");

             $("#" + id + " .picturegroup #erwm").css("height","'+(height+spanHeight)+'+'px'");

          }*/

          $('.theme-popover-mask').fadeOut(100);

          $('.theme-popover').slideUp(200);

         

          //恢复默认值

          CKEDITORHandler.isMultiseriate = false;

          CKEDITORHandler.editObj = null;

       }

   }

})(jQuery);

 

/**

 * 1、页面加载完成后执行的动作

 */

$(function(){

   $('.theme-poptit .close').click(function(){

      $('.theme-popover-mask').fadeOut(100);

      $('.theme-popover').slideUp(200);

   });

});

 

关于图片上传的后台操作,使用的框架是Spring+SpringMVC+MyBatis

package XXX.controller.upload;

 

import org.apache.log4j.Logger;

 

@Controller

@RequestMapping(value = "/import", method = { RequestMethod.GET,RequestMethod.POST })

public class ImportController extends BaseController{

         /** 用于打印日志 */

         private static final Logger logger = Logger

                            .getLogger(SpecialController.class);

        

         /**

          * 此方法用于CKEditor的本地上传图片的功能

          *

          * @param param

          * @param imageFile

          * @return

          */

         @RequestMapping(value = "/ckeditorUploadFile", produces = "text/json")

         public void ckeditorUploadFile(

                            @RequestParam("upload") MultipartFile upload,

                            HttpServletRequest request,

                            HttpServletResponse response,

                            @RequestParam("CKEditorFuncNum")String CKEditorFuncNum)

                            throws IllegalStateException,IOException {

                  

                   PrintWriter out = response.getWriter();

                   response.setCharacterEncoding("utf-8");

 

                   //判断扩展文件名是否正确

                   String uploadContentType = upload.getContentType();

                   if(uploadContentType.equals("image/pjpeg") || uploadContentType.equals("image/jpeg")) {

                           

                   } else if(uploadContentType.equals("image/png") || uploadContentType.equals("image/x-png")) {

                           

                   } else if(uploadContentType.equals("image/gif")) {

                           

                   } else if(uploadContentType.equals("image/bmp")) {

                           

                   } else {

                            out.println("<script type=\"text/javascript\">");

                            out.println("window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ",''," + "'文件格式不正确(必须为.jpg/.gif/.bmp/.png文件)');");

                            out.println("</script>");

                           

                            return;

                   }

                  

                   if (!upload.isEmpty()) {

                            try {

                                     //如果上传的图片大于10M,返回提示

                                     if (upload.getSize() > 10 * 1024 * 1024) {

                                               out.println("<script type=\"text/javascript\">");

                                               out.println("window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ",''," + "'文件大小不得大于600k');");

                                               out.println("</script>");

 

                                               return;

                                     }

                                    

                                     Calendar calendar = Calendar.getInstance();//获取当前时间

                                     //时间路径,解压文件,以年月日创建文件夹

                                     String dataPath ="/"+calendar.get(Calendar.YEAR)+"/"

                                                                 + (calendar.get(Calendar.MONTH)+1)+"/" + calendar.get(Calendar.DATE)+"/";

                                     // 原文件名

                                     String srcName = upload.getOriginalFilename();

                                     //获取上传文件后缀

                                     String suffix = srcName.substring(srcName.lastIndexOf(".") + 1,

                                                        srcName.length()).toLowerCase();

                                     //随机生成32id,用于解压文件目录

                                     String uuid = UUIDGenerator.generate();

                                     //新的文件名,随机的uuid;

                                     String picName = uuid +"."+suffix;

                                    

                                     //图片存储的实际路径

                                     String urlPrefix = ExtendedServerConfig.getInstance().getStringProperty("VISITE_PREFIX_URL");

                                     //大图缩略图生成路径

                                     String thumbnailPath =ExtendedServerConfig.getInstance()

                                                                 .getStringProperty("THUMBNAIL_PATH")+ ExtendedServerConfig.getInstance()

                                                                 .getStringProperty("SAVE_BIG_THUMBNAIL")+dataPath;

                                     //生成缩略图保存数据库路径

                                     String savePath =ExtendedServerConfig.getInstance()

                                                        .getStringProperty("SAVE_BIG_THUMBNAIL")+dataPath+picName;

                                     //文件夹不存在,则创建

                                     File destfile = new File(thumbnailPath);

                                if(!destfile.exists()){

                                         destfile.mkdirs();

                                }

                                     // 写文件

                                     InputStream fi = upload.getInputStream();

                                     //上传文件写入到配置文件夹下

                                     FileUtils.writeFile(fi, thumbnailPath+picName);

                                     File file = new File(thumbnailPath+picName);

                                     if(file.exists()) {

                                               out.println("<script type=\"text/javascript\">");

                                               out.println("window.parent.CKEDITOR.tools.callFunction(" + CKEditorFuncNum + ",'" + urlPrefix + savePath + "','')");

                                               out.println("</script>");

 

                                               return;

                                     }

                            } catch (Exception e) {

                                     e.printStackTrace();

                            }

                   }

                   return;

         }

}

 

 

 

 


目录
相关文章
|
2月前
|
SQL XML Java
mybatis复习01,简单配置让mybatis跑起来
文章介绍了MyBatis的基本概念、历史和特点,并详细指导了如何配置MyBatis环境,包括创建Maven项目、添加依赖、编写核心配置文件、创建数据表和实体类、编写Mapper接口和XML配置文件,以及如何编写工具类和测试用例。
mybatis复习01,简单配置让mybatis跑起来
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
XML JSON 数据库
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
这篇文章详细介绍了RESTful的概念、实现方式,以及如何在SpringMVC中使用HiddenHttpMethodFilter来处理PUT和DELETE请求,并通过具体代码案例分析了RESTful的使用。
SpringMVC入门到实战------七、RESTful的详细介绍和使用 具体代码案例分析(一)
|
3月前
|
安全 Java 数据库连接
后端框架的学习----mybatis框架(3、配置解析)
这篇文章详细介绍了MyBatis框架的核心配置文件解析,包括环境配置、属性配置、类型别名设置、映射器注册以及SqlSessionFactory和SqlSession的生命周期和作用域管理。
后端框架的学习----mybatis框架(3、配置解析)
|
2月前
|
SQL XML Java
mybatis :sqlmapconfig.xml配置 ++++Mapper XML 文件(sql/insert/delete/update/select)(增删改查)用法
当然,这些仅是MyBatis功能的初步介绍。MyBatis还提供了高级特性,如动态SQL、类型处理器、插件等,可以进一步提供对数据库交互的强大支持和灵活性。希望上述内容对您理解MyBatis的基本操作有所帮助。在实际使用中,您可能还需要根据具体的业务要求调整和优化SQL语句和配置。
44 1
|
3月前
|
前端开发 应用服务中间件 数据库
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
这篇文章通过一个具体的项目案例,详细讲解了如何使用SpringMVC、Thymeleaf、Bootstrap以及RESTful风格接口来实现员工信息的增删改查功能。文章提供了项目结构、配置文件、控制器、数据访问对象、实体类和前端页面的完整源码,并展示了实现效果的截图。项目的目的是锻炼使用RESTful风格的接口开发,虽然数据是假数据并未连接数据库,但提供了一个很好的实践机会。文章最后强调了这一章节主要是为了练习RESTful,其他方面暂不考虑。
SpringMVC入门到实战------八、RESTful案例。SpringMVC+thymeleaf+BootStrap+RestFul实现员工信息的增删改查
SpringMVC入门到实战------3、@RequestMapping注解(超详细基础知识+实际代码案例)
该博客文章详细介绍了SpringMVC中`@RequestMapping`注解的使用方法,包括其功能、位置、value属性、method属性、params属性、headers属性以及支持的路径风格和占位符,并通过实际代码案例展示了如何建立请求与控制器方法之间的映射关系。
SpringMVC入门到实战------3、@RequestMapping注解(超详细基础知识+实际代码案例)
|
3月前
|
缓存 Java 数据库连接
mybatis1.常见配置
本文介绍了MyBatis框架中的常见配置及其加载顺序。配置可通过`properties`元素、资源文件或方法参数传递,其中方法参数传递的属性具有最高优先级。文章列举了几个重要的配置项,如`cacheEnabled`用于全局开启或关闭缓存功能;`lazyLoadingEnabled`控制对象的延迟加载行为;`useGeneratedKeys`允许JDBC支持自动生成主键;`defaultExecutorType`设定默认执行器类型等。此外,还介绍了多环境配置方法,通过`environments`元素可定义不同环境下的数据库连接信息,并可根据需求动态选择加载特定环境
|
4月前
|
开发工具
vi编辑器,现在vi\vim是文本文件进行编辑的最佳选择,Vim是vi的加强的版本,兼容vi的所有指令,vim编辑器有三种工作模式,一开始进入的是命令模式,命令模式i是插入的意思,两下y+p复制内容
vi编辑器,现在vi\vim是文本文件进行编辑的最佳选择,Vim是vi的加强的版本,兼容vi的所有指令,vim编辑器有三种工作模式,一开始进入的是命令模式,命令模式i是插入的意思,两下y+p复制内容
|
5月前
|
开发工具
Vim 编辑器:高效文本编辑的瑞士军刀
**Vim 概览:** Vim 是一个功能丰富的文本编辑器,以其高度可定制性著称。文章介绍了 Vim 的高效使用技巧,包括快捷打开文件、命令行模式下的常用命令、查找与替换、删除和复制文本。还讨论了配置 `.vimrc` 文件以自定义设置,如改变 leader 键、设置缩进和高亮,并展示了安装插件如 vim-airline 和 vim-snazzy 的方法。通过这些技巧,用户能提升 Vim 使用效率。
66 5