diff --git a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee index e93c330573..55eb2cb179 100644 --- a/services/web/public/coffee/ide/editor/directives/aceEditor.coffee +++ b/services/web/public/coffee/ide/editor/directives/aceEditor.coffee @@ -15,6 +15,7 @@ define [ "ide/metadata/services/metadata" "ide/graphics/services/graphics" "ide/preamble/services/preamble" + "ide/files/services/files" ], (App, Ace, SearchBox, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager, MetadataManager, LabelsManager) -> EditSession = ace.require('ace/edit_session').EditSession ModeList = ace.require('ace/ext/modelist') @@ -37,7 +38,7 @@ define [ url = ace.config._moduleUrl(args...) + "?fingerprint=#{window.aceFingerprint}" return url - App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, metadata, graphics, preamble, $http, $q) -> + App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, metadata, graphics, preamble, files, $http, $q) -> monkeyPatchSearch($rootScope, $compile) return { @@ -106,7 +107,7 @@ define [ trackChangesManager = new TrackChangesManager(scope, editor, element) labelsManager = new LabelsManager(scope, editor, element, labels) metadataManager = new MetadataManager(scope, editor, element, metadata) - autoCompleteManager = new AutoCompleteManager(scope, editor, element, metadataManager, labelsManager, graphics, preamble) + autoCompleteManager = new AutoCompleteManager(scope, editor, element, metadataManager, labelsManager, graphics, preamble, files) # Prevert Ctrl|Cmd-S from triggering save dialog 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 53b3eac261..542b8ae69f 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 @@ -10,7 +10,7 @@ define [ aceSnippetManager = ace.require('ace/snippets').snippetManager class AutoCompleteManager - constructor: (@$scope, @editor, @element, @metadataManager, @labelsManager, @graphics, @preamble) -> + constructor: (@$scope, @editor, @element, @metadataManager, @labelsManager, @graphics, @preamble, @files) -> @monkeyPatchAutocomplete() @@ -41,6 +41,8 @@ define [ Graphics = @graphics Preamble = @preamble + Files = @files + GraphicsCompleter = getCompletions: (editor, session, pos, prefix, callback) -> context = Helpers.getContext(editor, pos) @@ -67,6 +69,27 @@ define [ callback null, result metadataManager = @metadataManager + 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 + LabelsCompleter = getCompletions: (editor, session, pos, prefix, callback) -> context = Helpers.getContext(editor, pos) @@ -136,6 +159,7 @@ define [ ReferencesCompleter LabelsCompleter 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..58e0598a3f --- /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|txt|md)/) + cloned = _.clone(entity) + cloned.path = path + texFiles.push cloned + return texFiles + + return Files