Просмотр исходного кода

Merge pull request #564 from sharelatex/sk-autocomplete-graphics

Sk autocomplete graphics
James Allen 9 лет назад
Родитель
Сommit
2f3c1fae86

+ 4 - 3
services/web/public/coffee/ide/editor/directives/aceEditor.coffee

@@ -11,6 +11,8 @@ define [
 	"ide/editor/directives/aceEditor/track-changes/TrackChangesManager"
 	"ide/editor/directives/aceEditor/labels/LabelsManager"
 	"ide/labels/services/labels"
+	"ide/graphics/services/graphics"
+	"ide/preamble/services/preamble"
 ], (App, Ace, SearchBox, ModeList, UndoManager, AutoCompleteManager, SpellCheckManager, HighlightsManager, CursorPositionManager, TrackChangesManager, LabelsManager) ->
 	EditSession = ace.require('ace/edit_session').EditSession
 	ModeList = ace.require('ace/ext/modelist')
@@ -33,9 +35,8 @@ define [
 			url = ace.config._moduleUrl(args...) + "?fingerprint=#{window.aceFingerprint}"
 			return url
 
-	App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels) ->
+	App.directive "aceEditor", ($timeout, $compile, $rootScope, event_tracking, localStorage, $cacheFactory, labels, graphics, preamble) ->
 		monkeyPatchSearch($rootScope, $compile)
-		
 
 		return  {
 			scope: {
@@ -102,7 +103,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)
+				autoCompleteManager = new AutoCompleteManager(scope, editor, element, labelsManager, graphics, preamble)
 
 
 				# Prevert Ctrl|Cmd-S from triggering save dialog

+ 55 - 3
services/web/public/coffee/ide/editor/directives/aceEditor/auto-complete/AutoCompleteManager.coffee

@@ -17,7 +17,7 @@ define [
 		commandFragment?.match(/\\(\w+)\{/)?[1]
 
 	class AutoCompleteManager
-		constructor: (@$scope, @editor, @element, @labelsManager) ->
+		constructor: (@$scope, @editor, @element, @labelsManager, @graphics, @preamble) ->
 			@suggestionManager = new SuggestionManager()
 
 			@monkeyPatchAutocomplete()
@@ -44,6 +44,37 @@ define [
 
 			SnippetCompleter = new SnippetManager()
 
+			Graphics = @graphics
+			Preamble = @preamble
+			GraphicsCompleter =
+				getCompletions: (editor, session, pos, prefix, callback) ->
+					upToCursorRange = new Range(pos.row, 0, pos.row, pos.column)
+					lineUpToCursor = editor.getSession().getTextRange(upToCursorRange)
+					commandFragment = getLastCommandFragment(lineUpToCursor)
+					if commandFragment
+						match = commandFragment.match(/^~?\\(includegraphics(?:\[.*])?){([^}]*, *)?(\w*)/)
+						if match
+							beyondCursorRange = new Range(pos.row, pos.column, pos.row, 99999)
+							lineBeyondCursor = editor.getSession().getTextRange(beyondCursorRange)
+							needsClosingBrace = !lineBeyondCursor.match(/^[^{]*}/)
+							commandName = match[1]
+							currentArg = match[3]
+							graphicsPaths = Preamble.getGraphicsPaths()
+							result = []
+							for graphic in Graphics.getGraphicsFiles()
+								path = graphic.path
+								for graphicsPath in graphicsPaths
+									if path.indexOf(graphicsPath) == 0
+										path = path.slice(graphicsPath.length)
+										break
+								result.push {
+									caption: "\\#{commandName}{#{path}#{if needsClosingBrace then '}' else ''}",
+									value: "\\#{commandName}{#{path}#{if needsClosingBrace then '}' else ''}",
+									meta: "graphic",
+									score: 50
+								}
+							callback null, result
+
 			labelsManager = @labelsManager
 			LabelsCompleter =
 				getCompletions: (editor, session, pos, prefix, callback) ->
@@ -112,7 +143,13 @@ define [
 							else
 								callback null, result
 
-			@editor.completers = [@suggestionManager, SnippetCompleter, ReferencesCompleter, LabelsCompleter]
+			@editor.completers = [
+				@suggestionManager,
+				SnippetCompleter,
+				ReferencesCompleter,
+				LabelsCompleter,
+				GraphicsCompleter
+			]
 
 		disable: () ->
 			@editor.setOptions({
@@ -245,7 +282,22 @@ define [
 						editor.completer.autoSelect = true
 						editor.completer.showPopup(editor)
 						editor.completer.cancelContextMenu()
-						$(editor.completer.popup?.container).css({'font-size': @$scope.fontSize + 'px'})
+						container = $(editor.completer.popup?.container)
+						container.css({'font-size': @$scope.fontSize + 'px'})
+						# Dynamically set width of autocomplete popup
+						if filtered = editor?.completer?.completions?.filtered
+							longestCaption = _.max(filtered.map( (c) -> c.caption.length ))
+							longestMeta = _.max(filtered.map( (c) -> c.meta.length ))
+							charWidth = editor.renderer.characterWidth
+							# between 280 and 700 px
+							width = Math.max(
+								Math.min(
+									Math.round(longestCaption*charWidth + longestMeta*charWidth + 5*charWidth),
+									700
+								),
+								280
+							)
+							container.css({width: "#{width}px"})
 						if editor.completer?.completions?.filtered?.length == 0
 							editor.completer.detach()
 					bindKey: "Ctrl-Space|Ctrl-Shift-Space|Alt-Space"

+ 17 - 0
services/web/public/coffee/ide/graphics/services/graphics.coffee

@@ -0,0 +1,17 @@
+define [
+	"base"
+], (App) ->
+
+	App.factory 'graphics', (ide) ->
+
+		Graphics =
+			getGraphicsFiles: () ->
+				graphicsFiles = []
+				ide.fileTreeManager.forEachEntity (entity, folder, path) ->
+					if entity.type == 'file' && entity?.name?.match?(/.*\.(png|jpg|jpeg|pdf|eps)/)
+						cloned = _.clone(entity)
+						cloned.path = path
+						graphicsFiles.push cloned
+				return graphicsFiles
+
+		return Graphics

+ 22 - 0
services/web/public/coffee/ide/preamble/services/preamble.coffee

@@ -0,0 +1,22 @@
+define [
+	"base"
+], (App) ->
+
+	App.factory 'preamble', (ide) ->
+
+		Preamble =
+			getPreambleText: () ->
+				text = ide.editorManager.getCurrentDocValue().slice(0, 5000)
+				preamble = text.match(/([^]*)^\\begin\{document\}/m)?[1] || ""
+				return preamble
+
+			getGraphicsPaths: () ->
+				preamble = Preamble.getPreambleText()
+				graphicsPathsArgs = preamble.match(/\\graphicspath\{(.*)\}/)?[1] || ""
+				paths = []
+				re = /\{([^}]*)\}/g
+				while match = re.exec(graphicsPathsArgs)
+					paths.push(match[1])
+				return paths
+
+		return Preamble

+ 1 - 0
services/web/public/stylesheets/app/editor.less

@@ -504,3 +504,4 @@
 	height: auto;
 	border-bottom: 1px solid @modal-header-border-color;
 }
+