Browse Source

增加 Cmd/Ctrl + / 键切换注释快捷键。#139

oldj 9 years ago
parent
commit
db859a64a3
7 changed files with 289 additions and 25 deletions
  1. 20 20
      README.md
  2. 238 2
      app/build/bundle.js
  3. 21 2
      app/src/components/content/editor.js
  4. 1 0
      app/src/lang/cn.js
  5. 1 0
      app/src/lang/en.js
  6. 7 0
      app/src/modules/mainMenu.js
  7. 1 1
      app/version.js

+ 20 - 20
README.md

@@ -36,43 +36,43 @@ SwitchHosts! 的数据文件在 `~/.SwitchHosts` 目录下(Windows 用户为
  - 在根目录 `./` 下,运行 `npm install` 命令,安装依赖库;
  - 在 `./app` 目录下,运行 `npm install` 命令,安装依赖库。
 
-```bash
-npm install
-cd app && npm install
-```
+    ```bash
+    npm install
+    cd app && npm install
+    ```
 
 ### 构建及运行
 
  - 在 `./` 目录下,运行 `npm run build` 命令,构建所需文件;
  - 在 `./` 目录下,运行 `npm start` 命令,即可运行程序。
 
-```bash
-# build
-npm run build
+    ```bash
+    # build
+    npm run build
 
-# start
-npm start
+    # start
+    npm start
 
-# start in developer mode
-npm run dev
-```
+    # start in developer mode
+    npm run dev
+    ```
 
 ### 打包发布
 
  - 在 `./` 目录下,运行 `npm run pack` 命令,打包后的文件位于 `./dist` 目录;
  - 首次执行此命令可能需要花费较多时间(需要下载对应的构建文件),更多信息请参考 [Electron 文档](http://electron.atom.io/docs/)。
 
-```bash
-# pack
-npm run pack  # the packed files will be in ./dist
-```
+    ```bash
+    # pack
+    npm run pack  # the packed files will be in ./dist
+    ```
 
  - 打包完成后,可运行以下命令将生成的程序压缩为 zip 文件。
 
-```bash
-# zip
-gulp zip  # the zipped files will be in ./dist
-```
+    ```bash
+    # zip
+    gulp zip  # the zipped files will be in ./dist
+    ```
 
 ## 更新历史:
 

+ 238 - 2
app/build/bundle.js

@@ -23369,7 +23369,7 @@
 
 	"use strict";
 	
-	exports.version = [3, 2, 0, 4177];
+	exports.version = [3, 2, 0, 4178];
 
 /***/ },
 /* 202 */
@@ -23600,7 +23600,6 @@
 /***/ function(module, exports, __webpack_require__) {
 
 	/**
-	 * editor
 	 * @author oldj
 	 * @blog http://oldj.net
 	 */
@@ -23621,6 +23620,8 @@
 	
 	var _codemirror2 = _interopRequireDefault(_codemirror);
 	
+	__webpack_require__(236);
+	
 	var _classnames = __webpack_require__(183);
 	
 	var _classnames2 = _interopRequireDefault(_classnames);
@@ -23644,6 +23645,8 @@
 	function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
 	
 	function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+	// import '../../../node_modules/codemirror/addon/comment/comment';
+	
 	
 	var Editor = function (_React$Component) {
 	    _inherits(Editor, _React$Component);
@@ -23689,6 +23692,21 @@
 	        value: function setValue(v) {
 	            this.props.setValue(v);
 	        }
+	    }, {
+	        key: 'toComment',
+	        value: function toComment() {
+	            var doc = this.codemirror.getDoc();
+	            var cur = doc.getCursor();
+	            var line = cur.line;
+	            var info = doc.lineInfo(line);
+	            this.codemirror.toggleComment({
+	                line: line,
+	                cur: 0
+	            }, {
+	                line: line,
+	                cur: info.text.length
+	            });
+	        }
 	    }, {
 	        key: 'componentDidMount',
 	        value: function componentDidMount() {
@@ -23725,6 +23743,10 @@
 	                _this3.codemirror.getDoc().replaceRange(new_ln, { line: info.line, ch: 0 }, { line: info.line, ch: ln.length });
 	                //app.caculateHosts();
 	            });
+	
+	            ipcRenderer.on('to_comment', function () {
+	                _this3.toComment();
+	            });
 	        }
 	    }, {
 	        key: 'componentWillReceiveProps',
@@ -34222,6 +34244,7 @@
 	exports.content = {
 	    _lang_name: 'English',
 	    add: 'Add',
+	    comment: 'Comment',
 	    new: 'New',
 	    quit: 'Quit',
 	    cancel: 'Cancel',
@@ -34298,6 +34321,7 @@
 	exports.content = {
 	    _lang_name: '简体中文',
 	    add: '添加',
+	    comment: '注释',
 	    new: '新建',
 	    quit: '退出',
 	    cancel: '取消',
@@ -34400,6 +34424,218 @@
 	// exports
 
 
+/***/ },
+/* 236 */
+/***/ function(module, exports, __webpack_require__) {
+
+	// CodeMirror, copyright (c) by Marijn Haverbeke and others
+	// Distributed under an MIT license: http://codemirror.net/LICENSE
+	
+	(function(mod) {
+	  if (true) // CommonJS
+	    mod(__webpack_require__(211));
+	  else if (typeof define == "function" && define.amd) // AMD
+	    define(["../../lib/codemirror"], mod);
+	  else // Plain browser env
+	    mod(CodeMirror);
+	})(function(CodeMirror) {
+	  "use strict";
+	
+	  var noOptions = {};
+	  var nonWS = /[^\s\u00a0]/;
+	  var Pos = CodeMirror.Pos;
+	
+	  function firstNonWS(str) {
+	    var found = str.search(nonWS);
+	    return found == -1 ? 0 : found;
+	  }
+	
+	  CodeMirror.commands.toggleComment = function(cm) {
+	    cm.toggleComment();
+	  };
+	
+	  CodeMirror.defineExtension("toggleComment", function(options) {
+	    if (!options) options = noOptions;
+	    var cm = this;
+	    var minLine = Infinity, ranges = this.listSelections(), mode = null;
+	    for (var i = ranges.length - 1; i >= 0; i--) {
+	      var from = ranges[i].from(), to = ranges[i].to();
+	      if (from.line >= minLine) continue;
+	      if (to.line >= minLine) to = Pos(minLine, 0);
+	      minLine = from.line;
+	      if (mode == null) {
+	        if (cm.uncomment(from, to, options)) mode = "un";
+	        else { cm.lineComment(from, to, options); mode = "line"; }
+	      } else if (mode == "un") {
+	        cm.uncomment(from, to, options);
+	      } else {
+	        cm.lineComment(from, to, options);
+	      }
+	    }
+	  });
+	
+	  // Rough heuristic to try and detect lines that are part of multi-line string
+	  function probablyInsideString(cm, pos, line) {
+	    return /\bstring\b/.test(cm.getTokenTypeAt(Pos(pos.line, 0))) && !/^[\'\"`]/.test(line)
+	  }
+	
+	  CodeMirror.defineExtension("lineComment", function(from, to, options) {
+	    if (!options) options = noOptions;
+	    var self = this, mode = self.getModeAt(from);
+	    var firstLine = self.getLine(from.line);
+	    if (firstLine == null || probablyInsideString(self, from, firstLine)) return;
+	
+	    var commentString = options.lineComment || mode.lineComment;
+	    if (!commentString) {
+	      if (options.blockCommentStart || mode.blockCommentStart) {
+	        options.fullLines = true;
+	        self.blockComment(from, to, options);
+	      }
+	      return;
+	    }
+	
+	    var end = Math.min(to.ch != 0 || to.line == from.line ? to.line + 1 : to.line, self.lastLine() + 1);
+	    var pad = options.padding == null ? " " : options.padding;
+	    var blankLines = options.commentBlankLines || from.line == to.line;
+	
+	    self.operation(function() {
+	      if (options.indent) {
+	        var baseString = null;
+	        for (var i = from.line; i < end; ++i) {
+	          var line = self.getLine(i);
+	          var whitespace = line.slice(0, firstNonWS(line));
+	          if (baseString == null || baseString.length > whitespace.length) {
+	            baseString = whitespace;
+	          }
+	        }
+	        for (var i = from.line; i < end; ++i) {
+	          var line = self.getLine(i), cut = baseString.length;
+	          if (!blankLines && !nonWS.test(line)) continue;
+	          if (line.slice(0, cut) != baseString) cut = firstNonWS(line);
+	          self.replaceRange(baseString + commentString + pad, Pos(i, 0), Pos(i, cut));
+	        }
+	      } else {
+	        for (var i = from.line; i < end; ++i) {
+	          if (blankLines || nonWS.test(self.getLine(i)))
+	            self.replaceRange(commentString + pad, Pos(i, 0));
+	        }
+	      }
+	    });
+	  });
+	
+	  CodeMirror.defineExtension("blockComment", function(from, to, options) {
+	    if (!options) options = noOptions;
+	    var self = this, mode = self.getModeAt(from);
+	    var startString = options.blockCommentStart || mode.blockCommentStart;
+	    var endString = options.blockCommentEnd || mode.blockCommentEnd;
+	    if (!startString || !endString) {
+	      if ((options.lineComment || mode.lineComment) && options.fullLines != false)
+	        self.lineComment(from, to, options);
+	      return;
+	    }
+	    if (/\bcomment\b/.test(self.getTokenTypeAt(Pos(from.line, 0)))) return
+	
+	    var end = Math.min(to.line, self.lastLine());
+	    if (end != from.line && to.ch == 0 && nonWS.test(self.getLine(end))) --end;
+	
+	    var pad = options.padding == null ? " " : options.padding;
+	    if (from.line > end) return;
+	
+	    self.operation(function() {
+	      if (options.fullLines != false) {
+	        var lastLineHasText = nonWS.test(self.getLine(end));
+	        self.replaceRange(pad + endString, Pos(end));
+	        self.replaceRange(startString + pad, Pos(from.line, 0));
+	        var lead = options.blockCommentLead || mode.blockCommentLead;
+	        if (lead != null) for (var i = from.line + 1; i <= end; ++i)
+	          if (i != end || lastLineHasText)
+	            self.replaceRange(lead + pad, Pos(i, 0));
+	      } else {
+	        self.replaceRange(endString, to);
+	        self.replaceRange(startString, from);
+	      }
+	    });
+	  });
+	
+	  CodeMirror.defineExtension("uncomment", function(from, to, options) {
+	    if (!options) options = noOptions;
+	    var self = this, mode = self.getModeAt(from);
+	    var end = Math.min(to.ch != 0 || to.line == from.line ? to.line : to.line - 1, self.lastLine()), start = Math.min(from.line, end);
+	
+	    // Try finding line comments
+	    var lineString = options.lineComment || mode.lineComment, lines = [];
+	    var pad = options.padding == null ? " " : options.padding, didSomething;
+	    lineComment: {
+	      if (!lineString) break lineComment;
+	      for (var i = start; i <= end; ++i) {
+	        var line = self.getLine(i);
+	        var found = line.indexOf(lineString);
+	        if (found > -1 && !/comment/.test(self.getTokenTypeAt(Pos(i, found + 1)))) found = -1;
+	        if (found == -1 && nonWS.test(line)) break lineComment;
+	        if (found > -1 && nonWS.test(line.slice(0, found))) break lineComment;
+	        lines.push(line);
+	      }
+	      self.operation(function() {
+	        for (var i = start; i <= end; ++i) {
+	          var line = lines[i - start];
+	          var pos = line.indexOf(lineString), endPos = pos + lineString.length;
+	          if (pos < 0) continue;
+	          if (line.slice(endPos, endPos + pad.length) == pad) endPos += pad.length;
+	          didSomething = true;
+	          self.replaceRange("", Pos(i, pos), Pos(i, endPos));
+	        }
+	      });
+	      if (didSomething) return true;
+	    }
+	
+	    // Try block comments
+	    var startString = options.blockCommentStart || mode.blockCommentStart;
+	    var endString = options.blockCommentEnd || mode.blockCommentEnd;
+	    if (!startString || !endString) return false;
+	    var lead = options.blockCommentLead || mode.blockCommentLead;
+	    var startLine = self.getLine(start), open = startLine.indexOf(startString)
+	    if (open == -1) return false
+	    var endLine = end == start ? startLine : self.getLine(end)
+	    var close = endLine.indexOf(endString, end == start ? open + startString.length : 0);
+	    if (close == -1 && start != end) {
+	      endLine = self.getLine(--end);
+	      close = endLine.indexOf(endString);
+	    }
+	    if (close == -1 ||
+	        !/comment/.test(self.getTokenTypeAt(Pos(start, open + 1))) ||
+	        !/comment/.test(self.getTokenTypeAt(Pos(end, close + 1))))
+	      return false;
+	
+	    // Avoid killing block comments completely outside the selection.
+	    // Positions of the last startString before the start of the selection, and the first endString after it.
+	    var lastStart = startLine.lastIndexOf(startString, from.ch);
+	    var firstEnd = lastStart == -1 ? -1 : startLine.slice(0, from.ch).indexOf(endString, lastStart + startString.length);
+	    if (lastStart != -1 && firstEnd != -1 && firstEnd + endString.length != from.ch) return false;
+	    // Positions of the first endString after the end of the selection, and the last startString before it.
+	    firstEnd = endLine.indexOf(endString, to.ch);
+	    var almostLastStart = endLine.slice(to.ch).lastIndexOf(startString, firstEnd - to.ch);
+	    lastStart = (firstEnd == -1 || almostLastStart == -1) ? -1 : to.ch + almostLastStart;
+	    if (firstEnd != -1 && lastStart != -1 && lastStart != to.ch) return false;
+	
+	    self.operation(function() {
+	      self.replaceRange("", Pos(end, close - (pad && endLine.slice(close - pad.length, close) == pad ? pad.length : 0)),
+	                        Pos(end, close + endString.length));
+	      var openEnd = open + startString.length;
+	      if (pad && startLine.slice(openEnd, openEnd + pad.length) == pad) openEnd += pad.length;
+	      self.replaceRange("", Pos(start, open), Pos(start, openEnd));
+	      if (lead) for (var i = start + 1; i <= end; ++i) {
+	        var line = self.getLine(i), found = line.indexOf(lead);
+	        if (found == -1 || nonWS.test(line.slice(0, found))) continue;
+	        var foundEnd = found + lead.length;
+	        if (pad && line.slice(foundEnd, foundEnd + pad.length) == pad) foundEnd += pad.length;
+	        self.replaceRange("", Pos(i, found), Pos(i, foundEnd));
+	      }
+	    });
+	    return true;
+	  });
+	});
+
+
 /***/ }
 /******/ ]);
 //# sourceMappingURL=bundle.js.map

+ 21 - 2
app/src/components/content/editor.js

@@ -1,5 +1,4 @@
 /**
- * editor
  * @author oldj
  * @blog http://oldj.net
  */
@@ -8,10 +7,12 @@
 
 import React from 'react';
 import CodeMirror from 'codemirror';
+// import '../../../node_modules/codemirror/addon/comment/comment';
+import 'codemirror/addon/comment/comment';
 import classnames from 'classnames';
 import modeHost from './cm_hl';
 import m_kw from '../../libs/kw';
-import '../../../node_modules/codemirror/lib/codemirror.css';
+import 'codemirror/lib/codemirror.css';
 import './editor.less'
 
 export default class Editor extends React.Component {
@@ -50,6 +51,20 @@ export default class Editor extends React.Component {
         this.props.setValue(v);
     }
 
+    toComment() {
+        let doc = this.codemirror.getDoc();
+        let cur = doc.getCursor();
+        let line = cur.line;
+        let info = doc.lineInfo(line);
+        this.codemirror.toggleComment({
+            line: line,
+            cur: 0
+        }, {
+            line: line,
+            cur: info.text.length
+        });
+    }
+
     componentDidMount() {
         // console.log(this.cnt_node, this.cnt_node.value);
         this.codemirror = CodeMirror.fromTextArea(this.cnt_node, {
@@ -82,6 +97,10 @@ export default class Editor extends React.Component {
             this.codemirror.getDoc().replaceRange(new_ln, {line: info.line, ch: 0}, {line: info.line, ch: ln.length});
             //app.caculateHosts();
         });
+
+        ipcRenderer.on('to_comment', () => {
+            this.toComment();
+        });
     }
 
     componentWillReceiveProps(next_props) {

+ 1 - 0
app/src/lang/cn.js

@@ -8,6 +8,7 @@
 exports.content = {
     _lang_name: '简体中文'
     , add: '添加'
+    , comment: '注释'
     , new: '新建'
     , quit: '退出'
     , cancel: '取消'

+ 1 - 0
app/src/lang/en.js

@@ -8,6 +8,7 @@
 exports.content = {
     _lang_name: 'English'
     , add: 'Add'
+    , comment: 'Comment'
     , new: 'New'
     , quit: 'Quit'
     , cancel: 'Cancel'

+ 7 - 0
app/src/modules/mainMenu.js

@@ -101,6 +101,13 @@ exports.init = function (app, sys_lang = 'en') {
                     // ipcMain.emit('to_search');
                     app.mainWindow.webContents.send('to_search');
                 }
+            }, {
+                label: lang.comment,
+                accelerator: 'CommandOrControl+/',
+                click () {
+                    // ipcMain.emit('to_search');
+                    app.mainWindow.webContents.send('to_comment');
+                }
             }]
         }, {
             label: lang.view,

+ 1 - 1
app/version.js

@@ -1 +1 @@
-exports.version = [3,2,0,4177];
+exports.version = [3,2,0,4178];