diff --git a/scripts/langindex.json b/scripts/langindex.json
index 22b33e825..3993e76f7 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -214,6 +214,9 @@
   "addon.messages.unabletomessage": "message",
   "addon.messages.unblockuser": "message",
   "addon.messages.unblockuserconfirm": "message",
+  "addon.messages.useentertosend": "message",
+  "addon.messages.useentertosenddescdesktop": "local_moodlemobileapp",
+  "addon.messages.useentertosenddescmac": "local_moodlemobileapp",
   "addon.messages.userwouldliketocontactyou": "message",
   "addon.messages.warningconversationmessagenotsent": "local_moodlemobileapp",
   "addon.messages.warningmessagenotsent": "local_moodlemobileapp",
@@ -602,6 +605,7 @@
   "addon.mod_lti.modulenameplural": "lti",
   "addon.mod_page.errorwhileloadingthepage": "local_moodlemobileapp",
   "addon.mod_page.modulenameplural": "page",
+  "addon.mod_quiz.answercolon": "qtype_numerical",
   "addon.mod_quiz.attemptfirst": "quiz",
   "addon.mod_quiz.attemptlast": "quiz",
   "addon.mod_quiz.attemptnumber": "quiz",
@@ -1246,6 +1250,7 @@
   "core.courses.enrolme": "local_moodlemobileapp",
   "core.courses.errorloadcategories": "local_moodlemobileapp",
   "core.courses.errorloadcourses": "local_moodlemobileapp",
+  "core.courses.errorloadplugins": "local_moodlemobileapp",
   "core.courses.errorsearching": "local_moodlemobileapp",
   "core.courses.errorselfenrol": "local_moodlemobileapp",
   "core.courses.filtermycourses": "local_moodlemobileapp",
diff --git a/src/addon/messages/lang/en.json b/src/addon/messages/lang/en.json
index 2ec162f66..75419bf5b 100644
--- a/src/addon/messages/lang/en.json
+++ b/src/addon/messages/lang/en.json
@@ -66,6 +66,9 @@
     "unabletomessage": "You are unable to message this user",
     "unblockuser": "Unblock user",
     "unblockuserconfirm": "Are you sure you want to unblock {{$a}}?",
+    "useentertosend": "Use enter to send",
+    "useentertosenddescdesktop": "If disabled, you can use Ctrl+Enter to send the message.",
+    "useentertosenddescmac": "If disabled, you can use Cmd+Enter to send the message.",
     "userwouldliketocontactyou": "{{$a}} would like to contact you",
     "warningconversationmessagenotsent": "Couldn't send message(s) to conversation {{conversation}}. {{error}}",
     "warningmessagenotsent": "Couldn't send message(s) to user {{user}}. {{error}}",
diff --git a/src/addon/messages/pages/settings/settings.html b/src/addon/messages/pages/settings/settings.html
index 4048bb8f6..0172888d9 100644
--- a/src/addon/messages/pages/settings/settings.html
+++ b/src/addon/messages/pages/settings/settings.html
@@ -32,6 +32,7 @@
             </ion-list>
         </ion-card>
 
+        <!-- Notifications. -->
         <ng-container *ngIf="preferences">
             <div *ngFor="let component of preferences.components">
                 <ion-card list *ngFor="let notification of component.notifications">
@@ -90,5 +91,20 @@
                 </ion-card>
             </div>
         </ng-container>
+
+        <!-- General settings. -->
+        <ion-card>
+            <ion-list text-wrap>
+                <ion-item-divider>{{ 'core.settings.general' | translate }}</ion-item-divider>
+                <ion-item text-wrap>
+                    <ion-label>
+                        <h2>{{ 'addon.messages.useentertosend' | translate }}</h2>
+                        <p *ngIf="isDesktop && !isMac">{{ 'addon.messages.useentertosenddescdesktop' | translate }}</p>
+                        <p *ngIf="isDesktop && isMac">{{ 'addon.messages.useentertosenddescmac' | translate }}</p>
+                    </ion-label>
+                    <ion-toggle [(ngModel)]="sendOnEnter" (ngModelChange)="sendOnEnterChanged()"></ion-toggle>
+                </ion-item>
+            </ion-list>
+        </ion-card>
     </core-loading>
 </ion-content>
diff --git a/src/addon/messages/pages/settings/settings.ts b/src/addon/messages/pages/settings/settings.ts
index 7b524ff3c..d7e30cd01 100644
--- a/src/addon/messages/pages/settings/settings.ts
+++ b/src/addon/messages/pages/settings/settings.ts
@@ -16,8 +16,12 @@ import { Component, OnDestroy } from '@angular/core';
 import { IonicPage } from 'ionic-angular';
 import { AddonMessagesProvider } from '../../providers/messages';
 import { CoreUserProvider } from '@core/user/providers/user';
-import { CoreDomUtilsProvider } from '@providers/utils/dom';
+import { CoreAppProvider } from '@providers/app';
+import { CoreConfigProvider } from '@providers/config';
+import { CoreEventsProvider } from '@providers/events';
 import { CoreSitesProvider } from '@providers/sites';
+import { CoreDomUtilsProvider } from '@providers/utils/dom';
+import { CoreConstants } from '@core/constants';
 
 /**
  * Page that displays the messages settings page.
@@ -39,16 +43,27 @@ export class AddonMessagesSettingsPage implements OnDestroy {
     courseMemberValue = AddonMessagesProvider.MESSAGE_PRIVACY_COURSEMEMBER;
     siteValue = AddonMessagesProvider.MESSAGE_PRIVACY_SITE;
     groupMessagingEnabled: boolean;
+    sendOnEnter: boolean;
+    isDesktop: boolean;
+    isMac: boolean;
 
     protected previousContactableValue: number | boolean;
 
     constructor(private messagesProvider: AddonMessagesProvider, private domUtils: CoreDomUtilsProvider,
-            private userProvider: CoreUserProvider, sitesProvider: CoreSitesProvider) {
+            private userProvider: CoreUserProvider, private sitesProvider: CoreSitesProvider, appProvider: CoreAppProvider,
+            private configProvider: CoreConfigProvider, private eventsProvider: CoreEventsProvider) {
 
         const currentSite = sitesProvider.getCurrentSite();
         this.advancedContactable = currentSite && currentSite.isVersionGreaterEqualThan('3.6');
         this.allowSiteMessaging = currentSite && currentSite.canUseAdvancedFeature('messagingallusers');
         this.groupMessagingEnabled = this.messagesProvider.isGroupMessagingEnabled();
+
+        this.configProvider.get(CoreConstants.SETTINGS_SEND_ON_ENTER, !appProvider.isMobile()).then((sendOnEnter) => {
+            this.sendOnEnter = !!sendOnEnter;
+        });
+
+        this.isDesktop = !appProvider.isMobile();
+        this.isMac = appProvider.isMac();
     }
 
     /**
@@ -233,6 +248,15 @@ export class AddonMessagesSettingsPage implements OnDestroy {
         });
     }
 
+    sendOnEnterChanged(): void {
+        // Save the value.
+        this.configProvider.set(CoreConstants.SETTINGS_SEND_ON_ENTER, this.sendOnEnter ? 1 : 0);
+
+        // Notify the app.
+        this.eventsProvider.trigger(CoreEventsProvider.SEND_ON_ENTER_CHANGED, {sendOnEnter: !!this.sendOnEnter},
+                this.sitesProvider.getCurrentSiteId());
+    }
+
     /**
      * Page destroyed.
      */
diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json
index 47566d043..048521fcd 100644
--- a/src/assets/lang/en.json
+++ b/src/assets/lang/en.json
@@ -214,6 +214,9 @@
     "addon.messages.unabletomessage": "You are unable to message this user",
     "addon.messages.unblockuser": "Unblock user",
     "addon.messages.unblockuserconfirm": "Are you sure you want to unblock {{$a}}?",
+    "addon.messages.useentertosend": "Use enter to send",
+    "addon.messages.useentertosenddescdesktop": "If disabled, you can use Ctrl+Enter to send the message.",
+    "addon.messages.useentertosenddescmac": "If disabled, you can use Cmd+Enter to send the message.",
     "addon.messages.userwouldliketocontactyou": "{{$a}} would like to contact you",
     "addon.messages.warningconversationmessagenotsent": "Couldn't send message(s) to conversation {{conversation}}. {{error}}",
     "addon.messages.warningmessagenotsent": "Couldn't send message(s) to user {{user}}. {{error}}",
diff --git a/src/components/send-message-form/core-send-message-form.html b/src/components/send-message-form/core-send-message-form.html
index aea20f503..f02a7ee2c 100644
--- a/src/components/send-message-form/core-send-message-form.html
+++ b/src/components/send-message-form/core-send-message-form.html
@@ -1,5 +1,5 @@
 <form>
-    <textarea class="core-send-message-input" [core-auto-focus]="showKeyboard" [placeholder]="placeholder" rows="1" core-auto-rows [(ngModel)]="message" name="message" (onResize)="textareaResized()"></textarea>
+    <textarea class="core-send-message-input" [core-auto-focus]="showKeyboard" [placeholder]="placeholder" rows="1" core-auto-rows [(ngModel)]="message" name="message" (onResize)="textareaResized()" (keydown.enter)="enterClicked($event)" (keydown.control.enter)="enterClicked($event, 'control')" (keydown.meta.enter)="enterClicked($event, 'meta')"></textarea>
     <ion-buttons end>
         <button ion-button icon-only clear="true" type="submit" [disabled]="!message" [attr.aria-label]="'core.send' | translate" [core-suppress-events] (onClick)="submitForm($event)">
             <ion-icon name="send" color="dark"></ion-icon>
diff --git a/src/components/send-message-form/send-message-form.ts b/src/components/send-message-form/send-message-form.ts
index bac82624d..ae7a25ff9 100644
--- a/src/components/send-message-form/send-message-form.ts
+++ b/src/components/send-message-form/send-message-form.ts
@@ -13,8 +13,13 @@
 // limitations under the License.
 
 import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
+import { CoreAppProvider } from '@providers/app';
+import { CoreConfigProvider } from '@providers/config';
+import { CoreEventsProvider } from '@providers/events';
+import { CoreSitesProvider } from '@providers/sites';
 import { CoreUtilsProvider } from '@providers/utils/utils';
 import { CoreTextUtilsProvider } from '@providers/utils/text';
+import { CoreConstants } from '@core/constants';
 
 /**
  * Component to display a "send message form".
@@ -37,9 +42,21 @@ export class CoreSendMessageFormComponent implements OnInit {
     @Output() onSubmit: EventEmitter<string>; // Send data when submitting the message form.
     @Output() onResize: EventEmitter<void>; // Emit when resizing the textarea.
 
-    constructor(private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider) {
+    protected sendOnEnter: boolean;
+
+    constructor(private utils: CoreUtilsProvider, private textUtils: CoreTextUtilsProvider, configProvider: CoreConfigProvider,
+            eventsProvider: CoreEventsProvider, sitesProvider: CoreSitesProvider, private appProvider: CoreAppProvider) {
+
         this.onSubmit = new EventEmitter();
         this.onResize = new EventEmitter();
+
+        configProvider.get(CoreConstants.SETTINGS_SEND_ON_ENTER, !this.appProvider.isMobile()).then((sendOnEnter) => {
+            this.sendOnEnter = !!sendOnEnter;
+        });
+
+        eventsProvider.on(CoreEventsProvider.SEND_ON_ENTER_CHANGED, (newValue) => {
+            this.sendOnEnter = newValue;
+        }, sitesProvider.getCurrentSiteId());
     }
 
     ngOnInit(): void {
@@ -74,4 +91,22 @@ export class CoreSendMessageFormComponent implements OnInit {
     textareaResized(): void {
         this.onResize.emit();
     }
+
+    /**
+     * Enter key clicked.
+     *
+     * @param {Event} e Event.
+     * @param {string} other The name of the other key that was clicked, undefined if no other key.
+     */
+    enterClicked(e: Event, other: string): void {
+        if (this.sendOnEnter && !other) {
+            // Enter clicked, send the message.
+            this.submitForm(e);
+        } else if (!this.sendOnEnter && !this.appProvider.isMobile()) {
+            if ((this.appProvider.isMac() && other == 'meta') || (!this.appProvider.isMac() && other == 'control')) {
+                // Cmd+Enter or Ctrl+Enter, send message.
+                this.submitForm(e);
+            }
+        }
+    }
 }
diff --git a/src/core/constants.ts b/src/core/constants.ts
index 79e131672..2fc8bfc79 100644
--- a/src/core/constants.ts
+++ b/src/core/constants.ts
@@ -32,6 +32,7 @@ export class CoreConstants {
     static SETTINGS_SYNC_ONLY_ON_WIFI = 'CoreSettingsSyncOnlyOnWifi';
     static SETTINGS_DEBUG_DISPLAY = 'CoreSettingsDebugDisplay';
     static SETTINGS_REPORT_IN_BACKGROUND = 'CoreSettingsReportInBackground'; // @deprecated since 3.5.0
+    static SETTINGS_SEND_ON_ENTER = 'CoreSettingsSendOnEnter';
 
     // WS constants.
     static WS_TIMEOUT = 30000;
diff --git a/src/providers/events.ts b/src/providers/events.ts
index 55def12a0..fca9550ed 100644
--- a/src/providers/events.ts
+++ b/src/providers/events.ts
@@ -58,6 +58,7 @@ export class CoreEventsProvider {
     static CORE_LOADING_CHANGED = 'core_loading_changed';
     static ORIENTATION_CHANGE = 'orientation_change';
     static LOAD_PAGE_MAIN_MENU = 'load_page_main_menu';
+    static SEND_ON_ENTER_CHANGED = 'send_on_enter_changed';
 
     protected logger;
     protected observables: { [s: string]: Subject<any> } = {};