From 2f03bb60153dfdfb35f707ead70c08cca924a545 Mon Sep 17 00:00:00 2001 From: Nate Stemen Date: Tue, 21 Nov 2017 11:26:44 -0500 Subject: [PATCH 1/2] adding file completer --- .../ide/editor/directives/aceEditor.coffee | 33 ++++++++++--------- .../auto-complete/AutoCompleteManager.coffee | 28 ++++++++++++++-- .../ide/file-tree/FileTreeManager.coffee | 32 +++++++++--------- .../coffee/ide/files/services/files.coffee | 17 ++++++++++ 4 files changed, 76 insertions(+), 34 deletions(-) create mode 100644 services/web/public/coffee/ide/files/services/files.coffee diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee index 577a3a0e75..d57fec5f3b 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee @@ -13,6 +13,7 @@ define [ "ide/labels/services/labels" "ide/graphics/services/graphics" "ide/preamble/services/preamble" + "ide/files/services/files" ], (App, Ace, SearchBox, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager, LabelsManager) -> EditSession = ace.require('ace/edit_session').EditSession ModeList = ace.require('ace/ext/modelist') @@ -35,7 +36,7 @@ define [ url = ace.config._moduleUrl(args...) + "?fingerprint=#{window.aceFingerprint}" return url - App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, graphics, preamble, $http) -> + App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, graphics, preamble, files, $http) -> monkeyPatchSearch($rootScope, $compile) return { @@ -103,7 +104,7 @@ define [ cursorPositionManager = new CursorPositionManager(scope, editor, element, localStorage) trackChangesManager = new TrackChangesManager(scope, editor, element) labelsManager = new LabelsManager(scope, editor, element, labels) - autoCompleteManager = new AutoCompleteManager(scope, editor, element, labelsManager, graphics, preamble) + autoCompleteManager = new AutoCompleteManager(scope, editor, element, labelsManager, graphics, preamble, files) # Prevert Ctrl|Cmd-S from triggering save dialog @@ -115,16 +116,16 @@ define [ editor.commands.removeCommand "transposeletters" editor.commands.removeCommand "showSettingsMenu" editor.commands.removeCommand "foldall" - + # For European keyboards, the / is above 7 so needs Shift pressing. - # This comes through as Command-Shift-/ on OS X, which is mapped to + # This comes through as Command-Shift-/ on OS X, which is mapped to # toggleBlockComment. # This doesn't do anything for LaTeX, so remap this to togglecomment to # work for European keyboards as normal. # On Windows, the key combo comes as Ctrl-Shift-7. editor.commands.removeCommand "toggleBlockComment" editor.commands.removeCommand "togglecomment" - + editor.commands.addCommand { name: "togglecomment", bindKey: { win: "Ctrl-/|Ctrl-Shift-7", mac: "Command-/|Command-Shift-/" }, @@ -140,7 +141,7 @@ define [ exec: (editor) -> ace.require("ace/ext/searchbox").Search(editor, true) readOnly: true - + # Bold text on CMD+B editor.commands.addCommand name: "bold", @@ -154,7 +155,7 @@ define [ text = editor.getCopyText() editor.insert("\\textbf{" + text + "}") readOnly: false - + # Italicise text on CMD+I editor.commands.addCommand name: "italics", @@ -171,7 +172,7 @@ define [ scope.$watch "onCtrlEnter", (callback) -> if callback? - editor.commands.addCommand + editor.commands.addCommand name: "compile", bindKey: win: "Ctrl-Enter", mac: "Command-Enter" exec: (editor) => @@ -180,7 +181,7 @@ define [ scope.$watch "onCtrlJ", (callback) -> if callback? - editor.commands.addCommand + editor.commands.addCommand name: "toggle-review-panel", bindKey: win: "Ctrl-J", mac: "Command-J" exec: (editor) => @@ -189,7 +190,7 @@ define [ scope.$watch "onCtrlShiftC", (callback) -> if callback? - editor.commands.addCommand + editor.commands.addCommand name: "add-new-comment", bindKey: win: "Ctrl-Shift-C", mac: "Command-Shift-C" exec: (editor) => @@ -198,7 +199,7 @@ define [ scope.$watch "onCtrlShiftA", (callback) -> if callback? - editor.commands.addCommand + editor.commands.addCommand name: "toggle-track-changes", bindKey: win: "Ctrl-Shift-A", mac: "Command-Shift-A" exec: (editor) => @@ -302,7 +303,7 @@ define [ if updateCount == 100 event_tracking.send 'editor-interaction', 'multi-doc-update' scope.$emit "#{scope.name}:change" - + onScroll = (scrollTop) -> return if !scope.eventsBridge? height = editor.renderer.layerConfig.maxHeight @@ -311,7 +312,7 @@ define [ onScrollbarVisibilityChanged = (event, vRenderer) -> return if !scope.eventsBridge? scope.eventsBridge.emit "aceScrollbarVisibilityChanged", vRenderer.scrollBarV.isVisible, vRenderer.scrollBarV.width - + if scope.eventsBridge? editor.renderer.on "scrollbarVisibilityChanged", onScrollbarVisibilityChanged @@ -401,14 +402,14 @@ define [ session = editor.getSession() session.off "changeScrollTop" - + doc = session.getDocument() doc.off "change", onChange - + editor.renderer.on "changeCharacterSize", () -> scope.$apply () -> scope.rendererData.lineHeight = editor.renderer.lineHeight - + scope.$watch "rendererData", (rendererData) -> if rendererData? rendererData.lineHeight = editor.renderer.lineHeight diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager.coffee index 170d75ce60..0e3ffe44d1 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager.coffee @@ -9,7 +9,7 @@ define [ aceSnippetManager = ace.require('ace/snippets').snippetManager class AutoCompleteManager - constructor: (@$scope, @editor, @element, @labelsManager, @graphics, @preamble) -> + constructor: (@$scope, @editor, @element, @labelsManager, @graphics, @preamble, @files) -> @suggestionManager = new CommandManager() @monkeyPatchAutocomplete() @@ -38,6 +38,8 @@ define [ Graphics = @graphics Preamble = @preamble + Files = @files + GraphicsCompleter = getCompletions: (editor, session, pos, prefix, callback) -> context = Helpers.getContext(editor, pos) @@ -63,6 +65,27 @@ define [ } callback null, result + FilesCompleter = + getCompletions: (editor, session, pos, prefix, callback) => + context = Helpers.getContext(editor, pos) + {lineUpToCursor, commandFragment, lineBeyondCursor, needsClosingBrace} = context + if commandFragment + match = commandFragment.match(/^\\(input|include){(\w*)/) + if match + commandName = match[1] + currentArg = match[2] + result = [] + for file in Files.getTeXFiles() + if file.id != @$scope.docId + path = file.path + result.push { + caption: "\\#{commandName}{#{path}#{if needsClosingBrace then '}' else ''}", + value: "\\#{commandName}{#{path}#{if needsClosingBrace then '}' else ''}", + meta: "file", + score: 50 + } + callback null, result + labelsManager = @labelsManager LabelsCompleter = getCompletions: (editor, session, pos, prefix, callback) -> @@ -130,7 +153,8 @@ define [ SnippetCompleter, ReferencesCompleter, LabelsCompleter, - GraphicsCompleter + GraphicsCompleter, + FilesCompleter ] disable: () -> diff --git a/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee b/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee index 0881e75cc8..a4583a0efd 100644 --- a/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee +++ b/services/web/public/coffee/ide/file-tree/FileTreeManager.coffee @@ -13,15 +13,15 @@ define [ @loadRootFolder() @loadDeletedDocs() @$scope.$emit "file-tree:initialized" - + @$scope.$watch "rootFolder", (rootFolder) => if rootFolder? @recalculateDocList() @_bindToSocketEvents() - + @$scope.multiSelectedCount = 0 - + $(document).on "click", => @clearMultiSelectedEntities() $scope.$digest() @@ -46,7 +46,7 @@ define [ type: "file" } @recalculateDocList() - + @ide.socket.on "reciveNewFolder", (parent_folder_id, folder) => parent_folder = @findEntityById(parent_folder_id) or @$scope.rootFolder @$scope.$apply () => @@ -85,25 +85,25 @@ define [ @ide.fileTreeManager.forEachEntity (entity) -> entity.selected = false entity.selected = true - + toggleMultiSelectEntity: (entity) -> entity.multiSelected = !entity.multiSelected @$scope.multiSelectedCount = @multiSelectedCount() - + multiSelectedCount: () -> count = 0 @forEachEntity (entity) -> if entity.multiSelected count++ return count - + getMultiSelectedEntities: () -> entities = [] @forEachEntity (e) -> if e.multiSelected entities.push e return entities - + getMultiSelectedEntityChildNodes: () -> entities = @getMultiSelectedEntities() paths = {} @@ -125,13 +125,13 @@ define [ if !prefixes[path]? child_entities.push entity return child_entities - + clearMultiSelectedEntities: () -> return if @$scope.multiSelectedCount == 0 # Be efficient, this is called a lot on 'click' @forEachEntity (entity) -> entity.multiSelected = false @$scope.multiSelectedCount = 0 - + multiSelectSelectedEntity: () -> @findSelectedEntity()?.multiSelected = true @@ -140,7 +140,7 @@ define [ return false if !folder? entity = @_findEntityByPathInFolder(folder, name) return entity? - + findSelectedEntity: () -> selected = null @forEachEntity (entity) -> @@ -178,7 +178,7 @@ define [ parts = path.split("/") name = parts.shift() rest = parts.join("/") - + if name == "." return @_findEntityByPathInFolder(folder, rest) @@ -268,7 +268,7 @@ define [ type: "doc" deleted: true } - + recalculateDocList: () -> @$scope.docs = [] @forEachEntity (entity, parentFolder, path) => @@ -287,7 +287,7 @@ define [ return -1 else return 1 - + getEntityPath: (entity) -> @_getEntityPathInFolder @$scope.rootFolder, entity @@ -349,7 +349,7 @@ define [ } deleteEntity: (entity, callback = (error) ->) -> - # We'll wait for the socket.io notification to + # We'll wait for the socket.io notification to # delete from scope. return @ide.queuedHttp { method: "DELETE" @@ -367,7 +367,7 @@ define [ folder_id: parent_folder.id _csrf: window.csrfToken } - + _isChildFolder: (parent_folder, child_folder) -> parent_path = @getEntityPath(parent_folder) or "" # null if root folder child_path = @getEntityPath(child_folder) or "" # null if root folder diff --git a/services/web/public/coffee/ide/files/services/files.coffee b/services/web/public/coffee/ide/files/services/files.coffee new file mode 100644 index 0000000000..a6b64f9f50 --- /dev/null +++ b/services/web/public/coffee/ide/files/services/files.coffee @@ -0,0 +1,17 @@ +define [ + "base" +], (App) -> + + App.factory 'files', (ide) -> + + Files = + getTeXFiles: () -> + texFiles = [] + ide.fileTreeManager.forEachEntity (entity, folder, path) -> + if entity.type == 'doc' && entity?.name?.match?(/.*\.(tex|sty|cls|dtx|ltx|def)/) + cloned = _.clone(entity) + cloned.path = path + texFiles.push cloned + return texFiles + + return Files From ac9e27713d023e2284615e204f0a5f117cc3dead Mon Sep 17 00:00:00 2001 From: Nate Stemen Date: Wed, 22 Nov 2017 11:25:02 -0500 Subject: [PATCH 2/2] changing allowed file types --- services/web/public/coffee/ide/files/services/files.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/services/web/public/coffee/ide/files/services/files.coffee b/services/web/public/coffee/ide/files/services/files.coffee index a6b64f9f50..58e0598a3f 100644 --- a/services/web/public/coffee/ide/files/services/files.coffee +++ b/services/web/public/coffee/ide/files/services/files.coffee @@ -8,7 +8,7 @@ define [ getTeXFiles: () -> texFiles = [] ide.fileTreeManager.forEachEntity (entity, folder, path) -> - if entity.type == 'doc' && entity?.name?.match?(/.*\.(tex|sty|cls|dtx|ltx|def)/) + if entity.type == 'doc' && entity?.name?.match?(/.*\.(tex|txt|md)/) cloned = _.clone(entity) cloned.path = path texFiles.push cloned